2009-05-23 8 views
13

Ich möchte das immer in größerem Maßstab mit unserem App + Build-System versuchen, aber höhere Prioritäten drängen es immer weiter zurück. Es scheint eine nette Möglichkeit zu sein, Guice-Module zu laden und vermeidet die übliche Beschwerde über "hart codierte Konfiguration". Die einzelnen Konfigurationseigenschaften ändern sich selten von selbst, aber Sie haben fast immer eine Reihe von Profilen, normalerweise für verschiedene Umgebungen (Debug, Produktion usw.).Hat jemand ServiceLoader zusammen mit Guice verwendet?

Mit ServiceLoader können Sie eine Liste aller Implementierungen abrufen, die als Service für einen bestimmten Typ definiert sind. Putting diese zusammen mit Guice, Sie am Ende mit:

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); 
     } 
    } 
} 

Anwendungsbeispiel (als dynamische Servlet-loader in einem guice-Servlet-Projekt):

import com.google.inject.servlet.ServletModule; 

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

Die Leistungen (als Module verpackt) wären in separaten JAR-Dateien verpackt. Innerhalb jeder Sie die Klasse definieren würde (n) in der Meta-Daten:

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

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

Da wir Maven verwenden, denken wir, dies wäre ideal, da wir in verschiedenen Ausführungen zur Laufzeit über Profil Abhängigkeiten ziehen konnte. Benutzt jemand Guice so?

Wenn nicht, können Sie dieses Beispiel verwenden und sehen, wie es für Sie funktioniert. (ServiceLoader wird nur in JDK6 + unterstützt)

+0

Können Sie helfen? Ich versuche etwas Ähnliches zu machen, habe aber ein Problem mit ServiceLoader? http://stackoverflow.com/questions/28983997/java-cant-get-a-working-serviceloader – tommed

Antwort

3

Wir machen fast genau das bei meiner Arbeit. Wir sind derzeit wegen einiger interner Einschränkungen in Java 5 stecken, also machen wir es etwas anders mit dem Service Provider (weil wir keinen Zugriff auf ServiceLocator haben, bis Java 6 wie du erwähnt hast), aber es funktioniert im Wesentlichen genauso.

Ich erinnere mich irgendwo zu lesen, dass dies eine der bevorzugten Möglichkeiten der Guice-Entwickler empfohlen wurde, obwohl sie dies für Flexibilität offen lassen wollen.

1

Ich dachte schon so, aber ich habe es nicht benutzt, weil ich Angst hatte, dass ich meine Module extrem klein halten muss, weil es unmöglich ist, dieselbe Schnittstelle zweimal zu binden. Mein Problem ist, dass, wenn ich eine Schnittstelle/Klasse/enum/was auch immer von einem anderen Glas verwenden möchte und dieses Glas eine services/* Datei definiert, bin ich geschraubt, weil ich den Inhalt des Glases nicht verwenden kann, ohne es als ein zu laden Modul.

Ich hoffe mein Anliegen ist klar.

0

"weil es unmöglich ist, die gleiche Schnittstelle zweimal zu binden."

Das ist in der Tat falsch! Mit Guices Multibinder gibt es eine Möglichkeit, mit verschiedenen Implementierungen derselben Schnittstelle zu arbeiten, die möglicherweise in verschiedenen Modulen gebunden sind.

Ich kam zu einer etwas anderen Lösung für das tatsächliche Laden als Mark Renouf (seine ModuleLoader sieht in der Tat besser), aber mein Blogbeitrag kann ein bisschen mehr über die Umgebung zeigen, wo dieser Ansatz anwendbar ist (Plugins) und was die Erweiterung Punkte sehen wie aus:

Guice 2.0 Multibinder + Java ServiceLoader = Plugin mechanism