2009-05-23 11 views
13

Je continue à vouloir essayer ceci à plus grande échelle avec notre système de construction app +, mais des priorités plus élevées continuent de le pousser au second plan. Cela semble être un bon moyen de charger les modules de Guice et d'éviter les plaintes fréquentes concernant la "configuration codée en dur". Les propriétés de configuration individuelles changent rarement d'elles-mêmes, mais vous aurez presque toujours un ensemble de profils, généralement pour des environnements différents (Debug, Production, etc.). ServiceLoader vous permet d'extraire une liste de toutes les implémentations définies en tant que service pour un type donné. Mettre cela avec Guice, vous vous retrouvez avec:Est-ce que quelqu'un a utilisé ServiceLoader avec Guice?

import java.util.ServiceLoader; 

import com.google.inject.AbstractModule; 
import com.google.inject.Module; 

public class ModuleLoader<M extends Module> extends AbstractModule { 

    private final Class<M> type; 

    public ModuleLoader(Class<M> type) { 
     this.type = type; 
    } 

    public static <M extends Module> ModuleLoader<M> of(Class<M> type) { 
     return new ModuleLoader<M>(type); 
    } 

    @Override 
    protected void configure() { 
     ServiceLoader<M> modules = ServiceLoader.load(type); 
     for (Module module : modules) { 
      install(module); 
     } 
    } 
} 

Exemple d'utilisation (comme chargeur de servlet dynamique dans un projet Guice-servlet):

import com.google.inject.servlet.ServletModule; 

public class ServletLoader extends GuiceServletContextListener { 
    @Override 
    protected final Injector getInjector() { 
     return Guice.createInjector(ModuleLoader.of(ServletModule.class); 
    } 
} 

Les services (emballés sous forme de modules) seraient emballé dans des fichiers de pot séparés. Au sein de chacun que vous souhaitez définir la classe (s) dans la méta-données:

Within servlets.jar: META-INF/services/com.google.inject.Module 

com.example.webapps.MyServletModuleA 
com.example.webapps.MyServletModuleB 

Depuis que nous utilisons Maven, nous pensons que ce serait idéal que nous pourrions tirer dans différentes implémentations à l'exécution via des dépendances de profil. Est-ce que quelqu'un utilise Guice comme ça? Si ce n'est pas le cas, n'hésitez pas à utiliser cet exemple et voyez comment cela fonctionne pour vous. (ServiceLoader n'est pris en charge que dans JDK6 +)

+0

Pouvez-vous aider? J'essaye de faire quelque chose de semblable mais ayant un problème noobie avec ServiceLoader? http://stackoverflow.com/questions/28983997/java-cant-get-a-working-serviceloader – tommed

Répondre

3

Nous faisons presque exactement cela à mon travail. Nous sommes actuellement bloqués dans Java 5 en raison de certaines limitations internes, donc nous le faisons un peu différemment en utilisant Service Provider (en raison de ne pas avoir accès à ServiceLocator jusqu'à java 6 comme vous l'avez mentionné), mais cela fonctionne essentiellement. Je me souviens d'avoir lu quelque part que c'était l'une des méthodes préférées recommandées par les développeurs de Guice, même s'ils voulaient laisser cela ouvert pour plus de flexibilité.

1

Je pensais déjà à cette façon mais je ne l'utilisais pas parce que j'avais peur, que je devais garder mes modules extrêmement petits, car il est impossible de lier deux fois la même interface. Mon problème est que si je veux utiliser une interface/class/enum/quoi d'un autre pot et que jar a défini un fichier services/* je suis foutu, parce que je ne peux pas utiliser le contenu du pot sans le charger comme un module.

J'espère que mon inquiétude est claire.

0

"parce qu'il est impossible de lier deux fois la même interface."

C'est en effet faux! Avec Multibinder de Guice, il est possible de travailler avec différentes implémentations de la même interface, éventuellement liées à différents modules. Je suis arrivé à une solution légèrement différente pour le chargement réel que Mark Renouf (son ModuleLoader semble en effet mieux), mais mon blog peut montrer un peu plus sur l'environnement où cette approche est applicable (Plugins) et quelle est l'extension les points ressemblent:

Guice 2.0 Multibinder + Java ServiceLoader = Plugin mechanism