Dependency injection mit Jersey-2.0
Ausgehend von Grund auf, ohne dass eine Vorherige Jersey 1.x wissen, ich habe eine harte Zeit zu verstehen, wie, um das setup dependency injection in meine Jersey-2.0-Projekt.
Ich verstehe auch, dass HK2 ist in Jersey 2.0, aber ich kann nicht scheinen zu finden, die docs, die helfen, mit Jersey-2.0-integration.
@ManagedBean
@Path("myresource")
public class MyResource {
@Inject
MyService myService;
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/getit")
public String getIt() {
return "Got it {" + myService + "}";
}
}
@Resource
@ManagedBean
public class MyService {
void serviceCall() {
System.out.print("Service calls");
}
}
pom.xml
<properties>
<jersey.version>2.0-rc1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jax-rs-ri</artifactId>
</dependency>
</dependencies>
Ich kann die container zu starten und zu dienen, meine Ressourcen, aber sobald ich hinzufügen, die @Inject zu MyService, das framework eine exception wirft:
SEVERE: Servlet.service() for servlet [com.noip.MyApplication] in context with path [/jaxrs] threw exception [A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.noip.MyResource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.noip.MyResource
] with root cause
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
Mein starter-Projekt ist verfügbar unter GitHub: https://github.com/donaldjarmstrong/jaxrs
InformationsquelleAutor donnie_armstrong | 2013-04-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie definieren eine
AbstractBinder
und registrieren Sie es in Ihrer JAX-RS-Anwendung. Der binder legt fest, wie die dependency injection sollten erstellen Sie Ihre Klassen.Wenn
@Inject
erkannt wird, ein parameter oder Feld vom TypMyService.class
es wird instanziiert mithilfe der KlasseMyService
. Die Verwendung dieser binder, Sie müssen registriert sein, mit der JAX-RS-Anwendung. In Ihremweb.xml
definieren Sie eine JAX-RS-Anwendung wie diese:Umsetzung der
MyApplication
Klasse (angegeben oben in deninit-param
).Binder Angabe von dependency injection ist eingetragen im Konstruktor der Klasse,, und wir auch sagen, die Anwendung, wo Sie zu finden der REST-Ressourcen (in deinem Fall
MyResource
) mit derpackages()
Methode aufrufen.Ich bin mir nicht sicher, was
EntityManager
ist, aber die Beurteilung durch docs.oracle.com/javaee/6/api/javax/persistence/... es scheint ein interface. Sie können binden Sie es mitbind(EntityManagerImpl.class).to(EntityManager.class)
(das binden einer KlasseEntityManagerImpl
Implementierung der SchnittstelleEntityManager
. Wenn Sie brauchen, um eine Fabrik, werfen Sie einen Blick aufbindFactory()
imAbstractBinder
. Wenn Sie hierbei Hilfe benötigen, erstellen Sie bitte eine neue Frage (ich will nicht Raum, Sie zu beantworten in den Kommentaren). Auch bin ich mir nicht sicher, dass Sie verwenden sollten, @PersistentContext, nur die Verwendung von @Inject für allesJa, EntityManager ist JPA (Java EE) bestimmte. Vielen Dank für Ihr Kommentar, ich werde zu öffnen, eine andere Frage, wenn ich ein bestimmtes problem!
Nur für das Protokoll, der PPV läuft auch auf Java SE. oracle.com/technetwork/java/javaee/tech/...
Was bedeutet binden? Was ist, wenn ich ein interface und eine Implementierung?
InformationsquelleAutor joscarsson
Zunächst einfach zu beantworten, einen Kommentar bei der Antwort akzeptiert.
Es liest einfach
bind( implementation ).to( contract )
. Sie können alternative Kette.in( scope )
. Standard-Umfang vonPerLookup
. Also, wenn Sie ein singleton ist, können SieEs gibt auch eine
RequestScoped
erhältlichAuch, statt
bind(Class).to(Class)
können Sie auchbind(Instance).to(Class)
werden, automatisch ein singleton.Hinzufügen, um die akzeptierte Antwort
Für diejenigen, die versuchen, um herauszufinden, wie sich zu registrieren Ihre
AbstractBinder
Umsetzung in Ihrem web.xml (d.h. Sie sind nicht mit einemResourceConfig
), scheint es, der binder wird nicht entdeckt, durch Paket Scannen, d.h.Oder dieser entweder
Um es zu arbeiten, ich hatte zu implementieren
Funktion
:Den
@Provider
annotation ermöglichen sollte, dieFeature
abgeholt werden, indem Sie das Paket Scannen. Oder ohne Paket Scannen, können Sie Sie explizit registrierenFeature
imweb.xml
Siehe Auch:
sowie Allgemeine Informationen aus der Jersey Dokumentation
UPDATE
Fabriken
Neben der grundlegenden Bindung in der akzeptierten Antwort, Sie haben auch Fabriken, in denen Sie komplexere Erstellung Logik, und haben auch Zugriff auf die Anfrage-Kontext-Informationen. Zum Beispiel
Dann können Sie injizieren
MyService
in Ihrem Ressource-Klasse.Mit
web.xml
obwohl dieconfigure()
aufHk2Feature
ist aufgerufen, die die Ressource anfordert, wirft einNullPointerException
. @PaulSamsothaInformationsquelleAutor Paul Samsotha
Die ausgewählte Antwort stammt aus eine Weile zurück. Es ist nicht sinnvoll zu erklären, jede Bindung in eine benutzerdefinierte HK2 binder.
Ich verwende Tomcat und ich musste hinzufügen einer Abhängigkeit. Obwohl es entworfen wurde, für den Glassfish-es passt perfekt in andere Behälter.
Stellen Sie sicher, Ihre container ist richtig konfiguriert (finden Sie in der Dokumentation).
Wir waren mit Schweißen für dependency injection, welches benötigt einige spezielle config für die Arbeit mit Tomcat (unsere Anwendung "container"). Wenn Sie mit Frühling, es funktioniert out of the box.
InformationsquelleAutor otonglet
Spät, aber ich hoffe, das jemand hilft.
Habe ich meine JAX RS, die wie folgt definiert:
Dann in meinen code endlich kann ich auch Spritzen:
In meinem Fall, die
SomeManagedBean
ist eine ApplicationScoped bean.Hoffe, das hilft niemandem.
InformationsquelleAutor gjijon
Oracle empfiehlt zur Beurteilung der @Path-annotation für alle Arten injiziert werden, wenn die Kombination von JAX-RS, CDI:
http://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced004.htm
Das ist zwar bei weitem nicht perfekt (z.B. Sie erhalten Warnung von Jersey beim Start), habe ich beschlossen, diese route, die mich rettet von der Wartung alle unterstützten Typen innerhalb einer Sammelmappe.
Beispiel:
InformationsquelleAutor Benjamin Mesing
Wenn Sie es vorziehen, zu verwenden, Guice, und Sie wollen nicht zu erklären, alle Bindungen, können Sie auch versuchen, diese adapter:
guice-bridge-jit-Injektor
InformationsquelleAutor Choi
Bei mir klappt es ohne
AbstractBinder
wenn ich auch die folgenden Abhängigkeiten in meine web-Anwendung (läuft auf Tomcat 8.5, Jersey 2.27):Klappt es mit der CDI 1.2 /CDI 2.0 für mich (mit Weld 2 /3).
InformationsquelleAutor lazlev