don*_*ong 106 java dependency-injection jersey jersey-2.0 hk2
从头开始没有任何以前的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");
}
}
Run Code Online (Sandbox Code Playgroud)
的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>
Run Code Online (Sandbox Code Playgroud)
我可以让容器启动并提供我的资源,但是只要我将@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)
Run Code Online (Sandbox Code Playgroud)
我的初学者项目可以在GitHub上找到:https://github.com/donaldjarmstrong/jaxrs
jos*_*son 104
您需要AbstractBinder在JAX-RS应用程序中定义并注册它.绑定器指定依赖注入应如何创建类.
public class MyApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(MyService.class).to(MyService.class);
}
}
Run Code Online (Sandbox Code Playgroud)
当@Inject在类型的参数或字段上检测到MyService.class它时,使用该类对其进行实例化MyService.要使用此绑定程序,需要在JAX-RS应用程序中注册.在您的web.xml定义JAX-RS应用程序中,如下所示:
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mypackage.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
实现MyApplication类(在上面指定init-param).
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(new MyApplicationBinder());
packages(true, "com.mypackage.rest");
}
}
Run Code Online (Sandbox Code Playgroud)
指定依赖项注入的绑定器在类的构造函数中注册,我们还MyResource使用packages()方法调用告诉应用程序在何处查找REST资源(在您的情况下).
Pau*_*tha 50
首先只是回答接受答案中的评论.
"绑定做什么?如果我有接口和实现怎么办?"
它只是读bind( implementation ).to( contract ).你可以替代链.in( scope ).默认范围PerLookup.所以,如果你想要一个单身人士,你可以
bind( implementation ).to( contract ).in( Singleton.class );
Run Code Online (Sandbox Code Playgroud)
还有一个RequestScoped可用的
另外,bind(Class).to(Class)您也bind(Instance).to(Class)可以自动成为单身人士.
添加到已接受的答案
对于那些试图弄清楚如何AbstractBinder在web.xml中注册实现的人(即你没有使用a 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>
Run Code Online (Sandbox Code Playgroud)
或者这个
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.foo.YourBinderImpl
</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)
为了让它工作,我不得不实现Feature:
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;
@Provider
public class Hk2Feature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AppBinder());
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
该@Provider注释应允许Feature由包扫描被拾起.或者没有包扫描,你可以明确地登记Feature在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>
Run Code Online (Sandbox Code Playgroud)
也可以看看:
以及来自Jersey文档的一般信息
除了已接受答案中的基本绑定外,您还拥有工厂,您可以在其中拥有更复杂的创建逻辑,还可以访问请求上下文信息.例如
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);
}
});
Run Code Online (Sandbox Code Playgroud)
然后你可以注入MyService你的资源类.
oto*_*let 12
选定的答案可以追溯到前一段时间.在自定义HK2活页夹中声明每个绑定是不切实际的.我正在使用Tomcat,我只需添加一个依赖项.尽管它是专为Glassfish设计的,但它完全适合其他容器.
<dependency>
<groupId>org.glassfish.jersey.containers.glassfish</groupId>
<artifactId>jersey-gf-cdi</artifactId>
<version>${jersey.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
确保您的容器也已正确配置(请参阅文档).
小智 5
迟到但我希望这有助于某人.
我的JAX RS定义如下:
@Path("/examplepath")
@RequestScoped //this make the diference
public class ExampleResource {
Run Code Online (Sandbox Code Playgroud)
然后,在我的代码中,我最终可以注入:
@Inject
SomeManagedBean bean;
Run Code Online (Sandbox Code Playgroud)
就我而言,它SomeManagedBean是一个ApplicationScoped bean.
希望这对任何人都有帮助.