从头开始没有任何以前的Jersey 1.x知识,我很难理解如何在我的Jersey 2.0项目中设置依赖注入 .
我也明白HK2可用于Jersey 2.0,但我似乎无法找到有助于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>
我可以让容器启动并提供我的资源,但是只要我将@Inject添加到MyService,框架就会抛出异常:
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)
我的初学者项目可在GitHub上找到:https://github.com/donaldjarmstrong/jaxrs
6 回答
您需要定义
AbstractBinder
并在JAX-RS应用程序中注册它 . Binders 指定依赖注入应如何创建类 .当在
MyService.class
类型的参数或字段上检测到@Inject
时,将使用类MyService
对其进行实例化 . 要使用此绑定程序,需要在JAX-RS应用程序中注册 . 在web.xml
中,定义一个这样的JAX-RS应用程序:实现
MyApplication
类(在init-param
中指定) .指定依赖项注入的绑定程序在类的构造函数中注册,我们还使用
packages()
方法调用告诉应用程序在何处查找REST资源(在您的情况下,MyResource
) .首先只是回答接受答案中的评论 .
它只是读取
bind( implementation ).to( contract )
. 你可以替代链.in( scope )
. 默认范围为PerLookup
. 所以,如果你想要一个单身人士,你可以还有
RequestScoped
可用此外,您也可以
bind(Instance).to(Class)
代替bind(Class).to(Class)
,它将自动成为单身人士 .添加到accepted answer
对于那些试图弄清楚如何在你的web.xml中注册
AbstractBinder
实现的人(即你没有使用ResourceConfig
),似乎不会通过包扫描发现 Binders ,即或者这个
为了让它工作,我必须实现Feature:
@Provider
注释应该允许包扫描拾取Feature
. 或者没有包扫描,您可以在web.xml
中明确注册Feature
See Also:
Custom Method Parameter Injection with Jersey
How to inject an object into jersey request context?
How do I properly configure an EntityManager in a jersey / hk2 application?
Request Scoped Injection into Singletons
以及来自Jersey文档的一般信息
更新
工厂
除了已接受答案中的基本绑定外,您还拥有工厂,您可以在其中拥有更复杂的创建逻辑,还可以访问请求上下文信息 . 例如
然后,您可以将
MyService
注入资源类 .选定的答案可以追溯到前一段时间 . 在自定义HK2 Binders 中声明每个绑定是不切实际的 . 我正在使用Tomcat,我只需添加一个依赖项 . 尽管它是专为Glassfish设计的,但它完全适合其他容器 .
确保您的容器也已正确配置(see the documentation) .
迟到但我希望这有助于某人 .
我的JAX RS定义如下:
然后,在我的代码中,我最终可以注入:
在我的例子中,
SomeManagedBean
是一个ApplicationScoped bean .希望这对任何人都有帮助 .
Oracle建议在将JAX-RS与CDI结合使用时将@Path注释添加到要注入的所有类型:http://docs.oracle.com/javaee/7/tutorial/jaxrs-advanced004.htm虽然这远非完美(例如你在启动时会收到来自Jersey的警告),但我决定采用这条路线,这样可以节省我在一个 Binders 中维护所有支持的类型 .
例:
如果您更喜欢使用Guice并且您不想声明所有绑定,您也可以尝试使用此适配器:
guice-bridge-jit-injector