2015-05-18 13 views
5

Ich habe nie zuvor guice verwendet, und ich wollte es in einem Beispielprojekt mit Jersey-basierten JAX-RS API, die von einer Service-Bean unterstützt wird, ausprobieren. Ich folgte dieser Anleitung: http://randomizedsort.blogspot.de/2011/05/using-guice-ified-jersey-in-embedded.html und konnte es zur Arbeit bringen. Mein Setup ist sehr einfach, eine JAX-RS-Ressource über Guice aufgerufen wird, und hat ein Feld, das @Inject und injiziert durch Guice kommentiert wird:auto scan für guice

@Path("configuration") 
@Produces(MediaType.APPLICATION_JSON) 
@Singleton 
public class ConfigurationResource { 

    @Inject 
    private ConfigurationService configurationService; 

So weit so gut, alles funktioniert, wie es sollte, außer folgenden: ich verwende GuiceServletContextListener für Dinge einstellen und jede Komponente nennen müssen explizit:

@WebListener 
public class GuiceInitializer extends GuiceServletContextListener{ 
    @Override 
    protected Injector getInjector() { 
     return Guice.createInjector(new JerseyServletModule() { 
      @Override 
      protected void configureServlets() { 
       //resources 
       bind(ConfigurationResource.class); 

       //services 
       bind(ConfigurationService.class).to(ConfigurationServiceImpl.class); 

       // Route all requests through GuiceContainer 
       serve("/management/*").with(GuiceContainer.class); 
      } 
     }); 
    } 
} 

ich finde es ziemlich unbequem alle Abhängigkeiten explizit zu nennen. Ich habe vorher mit dem Standalone-Trikot gearbeitet und kann Autos in definierten Paketen automatisch scannen. Auch Spring und CDI sind in der Lage, die Implementierung auf Schnittstellen zuzuordnen, ohne sie explizit benennen zu müssen.

Nun ist die Frage Teil:

  • gibt es eine Auto-Scan-Erweiterung/für guice Einstellung? Ich habe einige im Internet gefunden, aber es ist schwer zu sagen, welche von ihnen noch brauchbar und aktuell sind.

  • Gibt es noch eine andere Möglichkeit, die Konfiguration von Implementierungen und Ressourcen bequemer zu gestalten?

danke im voraus. Leon

+1

Auto -Scanning ermutigt Entwickler, nur Abhängigkeiten hinzuzufügen. Einer der Gründe, warum ich Guice mag, ist, dass Sie im Gegensatz zu Spring jedes Mal, wenn Sie eine Abhängigkeit hinzufügen, sich fragen müssen: "Macht diese Abhängigkeit Sinn? Ist es wirklich notwendig? Mache ich zu viel mit dieser Klasse?" –

+1

Hallo @ Jerry-Andrews, und danke für den Kommentar. Vielleicht verstehe ich Guice ein bisschen falsch. Ich wollte Guice als eine Möglichkeit verwenden, die javax.inject-Semantik ohne die Aufblähung von ejb/cdi oder spring zu verwenden. Auch ich denke in Bezug auf deinen Kommentar, dass, wenn ich eine Ressourcenklasse schreibe, es @ Path und @ GET annotatiere und was nicht, und die Logik hinter ihnen implementiere, habe ich bereits die Frage beantwortet "macht diese Ressource Sinn", und gezwungen, es zu einem Konfigurationsmodul hinzuzufügen, ist nur eine Quelle für dumme Fehler ... – Leon

+0

Vielleicht möchten Sie sich mit hk2 dafür beschäftigen, es kann Ihre Klassen zur Build-Zeit mit [hk2-metadata-generator] (https : //hk2.java.net/2.4.0-b24/inhabitant-generator.html) und dann können Sie die [hk2 bridge] (https://hk2.java.net/2.4.0-b24/apidocs/ org/glassfish/hk2/extras/ExtrasUtilities.html # bridgeServiceLocator% 28org.glassfish.hk2.api.ServiceLocator,% 20org.glassfish.hk2.api.ServiceLocator% 29) um es in den Jersey ServiceLocator zu integrieren – jwells131313

Antwort

3

Ich glaube nicht, Guice hat Unterstützung für etwas wie die Komponente-Scan von Spring-Framework eingebaut. Es ist jedoch nicht schwierig, dieses Feature in Guice zu simulieren.

Sie müssen lediglich einen Helfer-Modul wie folgt

import com.google.inject.AbstractModule; 
import org.reflections.Reflections; 

import java.lang.annotation.Annotation; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Set; 

/** 
* To use this helper module, call install(new ComponentScanModule("com.foo", Named.class); in the configure method of 
* another module class. 
*/ 
public final class ComponentScanModule extends AbstractModule { 
    private final String packageName; 
    private final Set<Class<? extends Annotation>> bindingAnnotations; 

    @SafeVarargs 
    public ComponentScanModule(String packageName, final Class<? extends Annotation>... bindingAnnotations) { 
     this.packageName = packageName; 
     this.bindingAnnotations = new HashSet<>(Arrays.asList(bindingAnnotations)); 
    } 

    @Override 
    public void configure() { 
     Reflections packageReflections = new Reflections(packageName); 
     bindingAnnotations.stream() 
      .map(packageReflections::getTypesAnnotatedWith) 
      .flatMap(Set::stream) 
      .forEach(this::bind); 
    } 
} 

Um Komponente scannen ein Paket wie com.foo und Unterpakete für Klassen schreiben @Singleton tragen, verwenden Sie es auf diese Weise:

public class AppModule extends AbstractModule { 
    public void configure() { 
    install(new ComponentScanModule("com.foo", Singleton.class)); 
    } 
}