Comenzando desde cero sin ningún conocimiento previo de Jersey 1.x, me cuesta entender cómo configurar la inyección de dependencia en mi proyecto de Jersey 2.0.
También entiendo que HK2 está disponible en Jersey 2.0, pero parece que no puedo encontrar documentos que ayuden con la integración de Jersey 2.0.
@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>
Puedo hacer que el contenedor se inicie y sirva mi recurso, pero tan pronto como agrego @Inject a MyService, el marco arroja una excepción:
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)
Mi proyecto inicial está disponible en GitHub: https://github.com/donaldjarmstrong/jaxrs
fuente
EntityManager
es, pero a juzgar por docs.oracle.com/javaee/6/api/javax/persistence/… parece ser una interfaz. Puede vincularlo usandobind(EntityManagerImpl.class).to(EntityManager.class)
(que vinculará una clase queEntityManagerImpl
implementa la interfazEntityManager
. Si necesita usar una fábrica, eche un vistazobindFactory()
en elAbstractBinder
. Si necesita ayuda con esto, cree una nueva pregunta (no tendré espacio para responda en los comentarios). Además, no estoy seguro de que deba usar @PersistentContext, solo use @Inject para todoPrimero solo para responder un comentario en la respuesta de aceptación.
Simplemente lee
bind( implementation ).to( contract )
. Puede cadena alternativa.in( scope )
. Alcance predeterminado dePerLookup
. Entonces, si quieres un singleton, puedesTambién hay un
RequestScoped
disponibleAdemás, en lugar de
bind(Class).to(Class)
, también puedebind(Instance).to(Class)
, que será automáticamente un singleton.Añadiendo a la respuesta aceptada
Para aquellos que intentan averiguar cómo registrar su
AbstractBinder
implementación en su web.xml (es decir, no está usando aResourceConfig
), parece que el aglutinante no se descubrirá a través del escaneo de paquetes, es decir,O esto tampoco
Para que funcione, tuve que implementar un
Feature
:La
@Provider
anotación debe permitir que elFeature
escaneo del paquete lo recoja. O sin escanear el paquete, puede registrar explícitamente elFeature
en elweb.xml
Ver también:
y para obtener información general de la documentación de Jersey
ACTUALIZAR
Suerte
Además del enlace básico en la respuesta aceptada, también tiene fábricas, donde puede tener una lógica de creación más compleja y también tener acceso para solicitar información de contexto. Por ejemplo
Luego puede inyectar
MyService
en su clase de recursos.fuente
web.xml
aunque se llame aconfigure()
onHk2Feature
, la solicitud de recurso arroja unNullPointerException
. @PaulSamsothaLa respuesta seleccionada data de hace un tiempo. No es práctico declarar todas las encuadernaciones en una encuadernación HK2 personalizada. Estoy usando Tomcat y solo tuve que agregar una dependencia. Aunque fue diseñado para Glassfish, encaja perfectamente en otros contenedores.
Asegúrese de que su contenedor también esté configurado correctamente ( consulte la documentación ).
fuente
Tarde, pero espero que esto ayude a alguien.
Tengo mi JAX RS definido así:
Entonces, en mi código finalmente puedo inyectar:
En mi caso, el
SomeManagedBean
es un bean ApplicationScoped.Espero que esto ayude a alguien.
fuente
Oracle recomienda agregar la anotación @Path a todos los tipos que se inyectarán al combinar JAX-RS con CDI: http://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced004.htm Aunque esto está lejos de ser perfecto ( por ejemplo, recibirá una advertencia de Jersey al inicio), decidí tomar esta ruta, lo que me evita mantener todos los tipos admitidos dentro de una carpeta.
Ejemplo:
fuente
Si prefiere utilizar Guice y no desea declarar todos los enlaces, también puede probar este adaptador:
inyector-puente-guice-jit
fuente
Para mí, funciona sin el
AbstractBinder
si incluyo las siguientes dependencias en mi aplicación web (que se ejecuta en Tomcat 8.5, Jersey 2.27):Funciona con CDI 1.2 / CDI 2.0 para mí (usando Weld 2/3 respectivamente).
fuente
Se requiere dependencia para un servicio reparador de Jersey y Tomcat es el servidor. donde $ {jersey.version} es 2.29.1
El código básico será el siguiente:
fuente