Java 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

从零开始,没有任何之前的Jersey 1.x知识,我很难理解如何在Jersey 2.0项目中设置依赖注入

我也知道Jersey 2.0中有HK2,但我似乎找不到有助于Jersey 2.0集成的文档

@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() {