Java Jersey 2.0的依赖注入
从零开始,没有任何之前的Jersey 1.x知识,我很难理解如何在Jersey 2.0项目中设置依赖注入 我也知道Jersey 2.0中有HK2,但我似乎找不到有助于Jersey 2.0集成的文档Java Jersey 2.0的依赖注入,java,dependency-injection,jersey,jersey-2.0,hk2,Java,Dependency Injection,Jersey,Jersey 2.0,Hk2,从零开始,没有任何之前的Jersey 1.x知识,我很难理解如何在Jersey 2.0项目中设置依赖注入 我也知道Jersey 2.0中有HK2,但我似乎找不到有助于Jersey 2.0集成的文档 @ManagedBean @路径(“我的资源”) 公共类MyResource{ @注入 我的服务我的服务; /** *方法处理HTTP GET请求。将发送返回的对象 *以“文本/普通”媒体类型发送到客户端。 * *@返回字符串,该字符串将作为文本/普通响应返回。 */ @得到 @产生(MediaTyp
@ManagedBean
@路径(“我的资源”)
公共类MyResource{
@注入
我的服务我的服务;
/**
*方法处理HTTP GET请求。将发送返回的对象
*以“文本/普通”媒体类型发送到客户端。
*
*@返回字符串,该字符串将作为文本/普通响应返回。
*/
@得到
@产生(MediaType.APPLICATION_JSON)
@路径(“/getit”)
公共字符串getIt(){
返回“gottit{”+myService+“}”;
}
}
@资源
@ManagedBean
公共类MyService{
void serviceCall(){
系统输出打印(“服务呼叫”);
}
}
pom.xml
2.0-rc1
UTF-8
org.glassfish.jersey
您需要定义一个AbstractBinder
,并在JAX-RS应用程序中注册它。绑定器指定依赖项注入应该如何创建类
公共类MyApplicationBinder扩展了AbstractBinder{
@凌驾
受保护的void configure(){
绑定(MyService.class).to(MyService.class);
}
}
当在类型为MyService.class
的参数或字段上检测到@Inject
时,将使用类MyService
对其进行实例化。要使用此绑定器,需要在JAX-RS应用程序中注册。在web.xml
中,定义如下JAX-RS应用程序:
@Path("/examplepath")
@RequestScoped //this make the diference
public class ExampleResource {
我的申请
org.glassfish.jersey.servlet.ServletContainer
javax.ws.rs.Application
com.mypackage.MyApplication
1.
我的申请
/*
实现MyApplication
类(在上面的init参数中指定)
公共类MyApplication扩展了ResourceConfig{
公共应用程序(){
注册(新MyApplicationBinder());
包(true,“com.mypackage.rest”);
}
}
指定依赖项注入的绑定器在类的构造函数中注册,我们还使用包()告诉应用程序在哪里可以找到REST资源(在您的例子中是MyResource
)
方法调用。Oracle建议在将JAX-RS与CDI组合时,向所有要注入的类型添加@Path注释:
虽然这还远远不够完美(例如,您在启动时会收到Jersey的警告),但我决定采用这一方法,这样可以避免在活页夹中维护所有受支持的类型
例如:
@Singleton
@Path("singleton-configuration-service")
public class ConfigurationService {
..
}
@Path("my-path")
class MyProvider {
@Inject ConfigurationService _configuration;
@GET
public Object get() {..}
}
如果您更喜欢使用Guice,并且不想声明所有绑定,也可以尝试以下适配器:
选定的答案可追溯到很久以前。在自定义HK2活页夹中声明每个绑定是不实际的。
我正在使用Tomcat,我只需要添加一个依赖项。即使它是为玻璃鱼设计的,但它也能完美地装入其他容器中
<dependency>
<groupId>org.glassfish.jersey.containers.glassfish</groupId>
<artifactId>jersey-gf-cdi</artifactId>
<version>${jersey.version}</version>
</dependency>
org.glassfish.jersey.containers.glassfish
).首先只是回答回答中的一条评论
“bind做什么?如果我有一个接口和一个实现怎么办?”
它只读取bind(implementation).to(contract)
。您可以在(范围)
中选择链。每个查找的默认范围PerLookup
。所以如果你想要单身,你可以
bind( implementation ).to( contract ).in( Singleton.class );
还有一个RequestScoped
可用
此外,您还可以将自动成为单例的bind(Instance).to(Class)
,而不是bind(Class).to(Class)
增加
对于那些试图弄清楚如何在web.xml中注册AbstractBinder
实现的人(即,您没有使用ResourceConfig
),似乎无法通过包扫描发现绑定,即
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
your.packages.to.scan
</param-value>
</init-param>
@Provider
注释应允许包扫描拾取功能。或者不进行包扫描,您可以在web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.foo.Hk2Feature
</param-value>
</init-param>
...
<load-on-startup>1</load-on-startup>
</servlet>
Jersey Web应用程序
org.glassfish.jersey.servlet.ServletContainer
jersey.config.server.provider.classnames
com.foo.hk2功能
...
1.
另请参见:
以及泽西岛文件中的一般信息
更新
工厂
除了接受答案中的基本绑定之外,您还可以使用工厂,在工厂中您可以拥有更复杂的创建逻辑,还可以访问请求上下文信息。比如说
public class MyServiceFactory implements Factory<MyService> {
@Context
private HttpHeaders headers;
@Override
public MyService provide() {
return new MyService(headers.getHeaderString("X-Header"));
}
@Override
public void dispose(MyService service) { /* noop */ }
}
register(new AbstractBinder() {
@Override
public void configure() {
bindFactory(MyServiceFactory.class).to(MyService.class)
.in(RequestScoped.class);
}
});
公共类MyServiceFactory实现工厂{
@上下文
私有HttpHeader;
@凌驾
公共MyService提供(){
返回新的MyService(headers.getHeaderString(“X-Header”);
}
@凌驾
public void dispose(MyService服务){/*noop*/}
}
注册(新的AbstractBinder(){
@凌驾
public void configure(){
bindFactory(MyServiceFactory.class).to(MyService.class)
.in(RequestScoped.class);
}
});
然后,您可以将MyService
注入资源类。很晚了,但我希望这对其他人有所帮助
我的JAX-RS定义如下:
@Path("/examplepath")
@RequestScoped //this make the diference
public class ExampleResource {
然后,在我的代码中,我最终可以注入:
@Inject
SomeManagedBean bean;
在我的例子中,SomeManagedBean
是一个应用程序范围的bean
希望这对任何人都有帮助。对我来说,如果我的web应用程序(运行在Tomcat 8.5、Jersey 2.27上)中包含以下依赖项,那么它就可以在没有AbstractBinder的情况下工作:
javax.ws.rs
javax.ws.rs-api
2.1
org.glassfish.jersey.containers
jersey容器servlet
${jersey版本}
@Path("/examplepath")
@RequestScoped //this make the diference
public class ExampleResource {
@Inject
SomeManagedBean bean;
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0.SP1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
@RequestScoped
@Path("test")
public class RESTEndpoint {
@GET
public String getMessage() {