Java 注入到Jersey资源类中
我确实试过浏览以下链接 和 但是,我仍然找不到一个工作示例来演示如何注入到资源类中。 我没有使用Spring或web容器 我的资源是Java 注入到Jersey资源类中,java,jersey,inject,Java,Jersey,Inject,我确实试过浏览以下链接 和 但是,我仍然找不到一个工作示例来演示如何注入到资源类中。 我没有使用Spring或web容器 我的资源是 package resource; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Path("/something") public cla
package resource;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/something")
public class Resource
{
@MyResource
Integer foo = null;
private static String response = "SampleData from Resource";
public Resource()
{
System.out.println("...constructor called :" + foo);
}
@Path("/that")
@GET
@Produces("text/plain")
public String sendResponse()
{
return response + "\n";
}
}
package resource;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
@Provider
public class MyResourceProvider implements InjectableProvider<MyResource, Integer>
{
@Override
public ComponentScope getScope()
{
return ComponentScope.PerRequest;
}
@Override
public Injectable getInjectable(final ComponentContext arg0, final MyResource arg1, final Integer arg2)
{
return new Injectable<Object>()
{
@Override
public Object getValue()
{
return new Integer(99);
}
};
}
}
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
class EndpointPublisher
{
public static void main(final String[] args)
{
final String address = "http://localhost:8080/";
final Map<String, String> config = new HashMap<String, String>();
config.put("com.sun.jersey.config.property.packages", "resource");
try
{
GrizzlyWebContainerFactory.create(address, config);
System.out.println("server started ....." + address);
callGet();
}
catch (final Exception e)
{
e.printStackTrace();
}
}
public static void callGet()
{
Client client = null;
ClientResponse response = null;
client = Client.create();
final WebResource resource =
client.resource("http://localhost:8080/something");
response = resource.path("that")
.accept(MediaType.TEXT_XML_TYPE, MediaType.APPLICATION_XML_TYPE)
.type(MediaType.TEXT_XML)
.get(ClientResponse.class);
System.out.println(">>>> " + response.getResponseDate());
}
}
我的提供商是
package resource;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/something")
public class Resource
{
@MyResource
Integer foo = null;
private static String response = "SampleData from Resource";
public Resource()
{
System.out.println("...constructor called :" + foo);
}
@Path("/that")
@GET
@Produces("text/plain")
public String sendResponse()
{
return response + "\n";
}
}
package resource;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
@Provider
public class MyResourceProvider implements InjectableProvider<MyResource, Integer>
{
@Override
public ComponentScope getScope()
{
return ComponentScope.PerRequest;
}
@Override
public Injectable getInjectable(final ComponentContext arg0, final MyResource arg1, final Integer arg2)
{
return new Injectable<Object>()
{
@Override
public Object getValue()
{
return new Integer(99);
}
};
}
}
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
class EndpointPublisher
{
public static void main(final String[] args)
{
final String address = "http://localhost:8080/";
final Map<String, String> config = new HashMap<String, String>();
config.put("com.sun.jersey.config.property.packages", "resource");
try
{
GrizzlyWebContainerFactory.create(address, config);
System.out.println("server started ....." + address);
callGet();
}
catch (final Exception e)
{
e.printStackTrace();
}
}
public static void callGet()
{
Client client = null;
ClientResponse response = null;
client = Client.create();
final WebResource resource =
client.resource("http://localhost:8080/something");
response = resource.path("that")
.accept(MediaType.TEXT_XML_TYPE, MediaType.APPLICATION_XML_TYPE)
.type(MediaType.TEXT_XML)
.get(ClientResponse.class);
System.out.println(">>>> " + response.getResponseDate());
}
}
但是当我执行EndpointPublisher时,我无法注入foo 您的InjectableProvider未正确实现。第二个类型参数不应该是您尝试注入的字段的类型,而应该是上下文——java.lang.reflect.type类或com.sun.jersey.api.model.parameter类。在您的情况下,您将使用Type。因此,您的InjectableProvider实现应该如下所示:
package resource;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
import java.lang.reflect.Type;
@Provider
public class MyResourceProvider implements InjectableProvider<MyResource, Type> {
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public Injectable getInjectable(final ComponentContext arg0, final MyResource arg1, final Type arg2) {
if (Integer.class.equals(arg2)) {
return new Injectable<Integer>() {
@Override
public Integer getValue() {
return new Integer(99);
}
};
} else {
return null;
}
}
}
包资源;
导入javax.ws.rs.ext.Provider;
导入com.sun.jersey.core.spi.component.ComponentContext;
导入com.sun.jersey.core.spi.component.ComponentScope;
导入com.sun.jersey.spi.inject.Injectable;
导入com.sun.jersey.spi.inject.InjectableProvider;
导入java.lang.reflect.Type;
@提供者
公共类MyResourceProvider实现了InjectableProvider{
@凌驾
公共组件范围getScope(){
返回ComponentScope.PerRequest;
}
@凌驾
公共可注入getInjectable(最终组件上下文arg0,最终MyResource arg1,最终类型arg2){
if(Integer.class.equals(arg2)){
返回新的可注射(){
@凌驾
公共整数getValue(){
返回新的整数(99);
}
};
}否则{
返回null;
}
}
}
每个请求可注入提供程序(PerRequestTypeInjectableProvider)和单例可注入提供程序(SingletonTypeInjectableProvider)都有一个助手类,因此您可以通过继承该类来进一步简化它:
package resource;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
@Provider
public class MyResourceProvider extends PerRequestTypeInjectableProvider<MyResource, Integer> {
public MyResourceProvider() {
super(Integer.class);
}
@Override
public Injectable<Integer> getInjectable(ComponentContext ic, MyResource a) {
return new Injectable<Integer>() {
@Override
public Integer getValue() {
return new Integer(99);
}
};
}
}
包资源;
导入javax.ws.rs.ext.Provider;
导入com.sun.jersey.core.spi.component.ComponentContext;
导入com.sun.jersey.spi.inject.Injectable;
导入com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
@提供者
公共类MyResourceProvider扩展了PerRequestTypeInjectableProvider{
公共MyResourceProvider(){
super(Integer.class);
}
@凌驾
公共可注入getInjectable(ComponentContext ic,MyResource a){
返回新的可注射(){
@凌驾
公共整数getValue(){
返回新的整数(99);
}
};
}
}
请注意,对于这些帮助器类,第二个类型参数是字段的类型
还有一件事-注入发生在调用构造函数后,因此资源的构造函数仍将打印出
…构造函数调用:null
,但是如果更改资源方法以返回foo,您将看到您将得到99的响应。此解决方案运行良好,我想与大家分享我在jersey resources上启用CDI的发现
下面是有史以来最简单的bean:
package fr.test;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
@RequestScoped
public class Test {
private int i;
@PostConstruct
public void create() {
i = 6;
}
public int getI() {
return i;
}
}
在资源类中,我们只是注入这个bean,就像在任何正常上下文中一样:
package fr.test;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/login")
public class LoginApi {
@Inject
private Test test;
@GET
@Produces("text/plain")
public String getIt() {
return "Hi there!" + test;
}
}
这是钥匙。我们定义了一个负责beans解析的Jersey“InjectionProvider”:
package fr.test;
import javax.inject.Inject;
import java.lang.reflect.Type;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
import fr.xxxxxxxxxx.ApplicationBeans;
@Provider
public class InjectionProvider implements InjectableProvider<Inject, Type> {
public ComponentScope getScope() {
// CDI will handle scopes for us
return ComponentScope.Singleton;
}
@Override
public Injectable<?> getInjectable(ComponentContext context,
Inject injectAnno, Type t) {
if (!(t instanceof Class))
throw new RuntimeException("not injecting a class type ?");
Class<?> clazz = (Class<?>) t;
final Object instance = ApplicationBeans.get(clazz);
return new Injectable<Object>() {
public Object getValue() {
return instance;
}
};
}
}
包装fr.test;
导入javax.inject.inject;
导入java.lang.reflect.Type;
导入javax.ws.rs.ext.Provider;
导入com.sun.jersey.core.spi.component.ComponentContext;
导入com.sun.jersey.core.spi.component.ComponentScope;
导入com.sun.jersey.spi.inject.Injectable;
导入com.sun.jersey.spi.inject.InjectableProvider;
导入fr.XXXXXXXXX.ApplicationBeans;
@提供者
公共类InjectionProvider实现InjectableProvider{
公共组件范围getScope(){
//CDI将为我们处理范围
返回ComponentScope.Singleton;
}
@凌驾
公共可注入getInjectable(ComponentContext上下文,
注入(无,t型){
如果(!(类的t实例))
抛出新的RuntimeException(“未注入类类型?”);
类clazz=(类)t;
最终对象实例=ApplicationBeans.get(clazz);
返回新的可注射(){
公共对象getValue(){
返回实例;
}
};
}
}
使用我们正在处理的注释类型和上下文类型(这里是普通java类型)进行类型化
ApplicationBeans只是bean解析的简单助手。内容如下:
package fr.xxxxxxxxxx;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import fr.xxxxxxxxxxxxx.UnexpectedException;
/**
* Gives direct access to managed beans - Designed to be used from unmanaged code
*
* @author lgrignon
*
*/
@ApplicationScoped
public class ApplicationBeans
{
protected static ApplicationBeans instance;
@Inject
private BeanManager beanManager;
/**
* Gets instance
*
* @return Instance from managed environment
*/
public static ApplicationBeans instance()
{
if (instance == null)
{
BeanManager beanManager;
InitialContext ctx = null;
try
{
ctx = new InitialContext();
beanManager = (BeanManager)ctx.lookup("java:comp/BeanManager");
}catch(NamingException e)
{
try
{
beanManager = (BeanManager)ctx.lookup("java:app/BeanManager");
}catch(NamingException ne)
{
throw new UnexpectedException("Unable to obtain BeanManager.", ne);
}
}
instance = getBeanFromManager(beanManager, ApplicationBeans.class);
}
return instance;
}
/**
* Gets bean instance from context
*
* @param <T>
* Bean's type
* @param beanType
* Bean's type
* @param annotations
* Bean's annotations
* @return Bean instance or null if no
*/
public static <T> T get(final Class<T> beanType, Annotation... annotations)
{
return instance().getBean(beanType, annotations);
}
/**
* Gets bean instance from context
*
* @param <T>
* Bean's type
* @param beanType
* Bean's type
* @param annotations
* Bean's annotations
* @return Bean instance or null if no
*/
public <T> T getBean(final Class<T> beanType, Annotation... annotations)
{
return getBeanFromManager(beanManager, beanType, annotations);
}
@SuppressWarnings("unchecked")
private static <T> T getBeanFromManager(BeanManager beanManager, final Class<T> beanType, Annotation... annotations)
{
Set<Bean<?>> beans = beanManager.getBeans(beanType, annotations);
if (beans.size() > 1)
{
throw new UnexpectedException("Many bean declarations found for type %s (%s)", beanType.getSimpleName(), beansToString(beans));
}
if (beans.isEmpty())
{
throw new UnexpectedException("No bean declaration found for type %s", beanType.getSimpleName());
}
final Bean<T> bean = (Bean<T>)beans.iterator().next();
final CreationalContext<T> context = beanManager.createCreationalContext(bean);
return (T)beanManager.getReference(bean, beanType, context);
}
private static String beansToString(Collection<Bean<?>> beans)
{
String[] beansLabels = new String[beans.size()];
int i = 0;
for (final Bean<?> bean : beans)
{
beansLabels[i++] = bean.getName();
}
return Arrays.toString(beansLabels);
}
}
包装fr.xxxxxxxxx;
导入java.lang.annotation.annotation;
导入java.util.array;
导入java.util.Collection;
导入java.util.Set;
导入javax.enterprise.context.ApplicationScoped;
导入javax.enterprise.context.spi.CreationContext;
导入javax.enterprise.inject.spi.Bean;
导入javax.enterprise.inject.spi.BeanManager;
导入javax.inject.inject;
导入javax.naming.InitialContext;
导入javax.naming.NamingException;
进口fr.XXXXXXXXXXXX。意外异常;
/**
*提供对托管bean的直接访问—设计用于非托管代码
*
*@author lgrignon
*
*/
@适用范围
公共类应用程序bean
{
受保护的静态ApplicationBeans实例;
@注入
专用BeanManager BeanManager;
/**
*获取实例
*
*@从托管环境返回实例
*/
公共静态ApplicationBeans实例()
{
if(实例==null)
{
BeanManager BeanManager;
InitialContext ctx=null;
尝试
{
ctx=新的InitialContext();
beanManager=(beanManager)ctx.lookup(“java:comp/beanManager”);
}捕获(NamingE例外)
{
尝试
{
beanManager=(beanManager)ctx.lookup(“java:app/beanManager”);
}捕获(纳明异常)
{
抛出新的意外异常(“无法获取BeanManager.”,ne);
}
}
instance=getBeanFromManager(beanManager,ApplicationBeans.class);
}
返回实例;
}
/**
*