我正在使用带有Glassfish 4.0的Jersey 2.8。 我有一个资源定位器类,如下所示
@Path("/")
@ManagedBean
public class MyServiceLocator {
@Context
ResourceContext rc;//javax.ws.rs.container.ResourceContext
@EJB
private MyEJBHome myEJB;
@Inject//javax.inject.Inject
MySubService mss;
@Path("/mysubservice")
public MySubService getMySubService() {
return rc.getResource(MySubService.class);
//also tried return rc.initResource(new MySubService());
}
}
和
的子资源类@ManagedBean
public class MySubService {
@EJB
public MyEJBHome myEJB;
@Context
HttpHeaders heads;
/*@Inject
private myEJBHome myEJB2;*/
@Path("/mypath")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Object doSomething(@Context SecurityContext securityContext) {...}
}
beans.xml
文件放在META-INF和WEB-INF。
在MyServiceLocator类private MyEJBHome myEJB
中成功注入。并成功注入MySubService mss
对象并将EJB注入其中。
问题是,当通过ResourceContext获取MySubService时,不会将EJB注入其中。
以前我使用Glassfish 3和Jersey 1.17使用专有的ResourceContext,绝对相同的代码工作正常。
我搜索了很多并阅读了很多相似(但有点不同)的问题,因为我理解非JAX-RS的东西(在我的情况下是EJB)在通过ResorceContext获取子资源时无法注入。这是真的吗?如果是的话我怎么能解决它? 一种可能的解决方案是将子资源对象注入资源定位器类,但是它们太多而且看起来非常难看。
编辑使用@Inject注入是否可以创建绑定器,将ejb类绑定到ejb接口并注册该绑定器。但我不想描述数百个ejbs的绑定。另外据我所知,这是特定的绑定杉木HK2系统,我不想与它链接。
设置@Named注释并尝试通过CDI注入的不同操作没有帮助。似乎当通过ResourceContext获取子资源时,Jersey只使用HK2,这就是为什么CDI无法完成它的工作。这是对的吗?
答案 0 :(得分:1)
我找到的唯一合适的解决方案是创建自己的注释并注入提供者。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EJBInject {
String beanName();
}
@Provider
public class EjbInjectProvider implements InjectionResolver<EJBInject> {
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
try {
String beanName = injectee.getParent().getAnnotation(EJBInject.class).beanName();
return new InitialContext().lookup("java:global/MyApp/" + beanName);
} catch (Exception e) {
return null;
}
}
@Override
public boolean isConstructorParameterIndicator() {
return false;
}
@Override
public boolean isMethodParameterIndicator() {
return false;
}
}
然后可以使用像
这样的注释注入ejb@EJBInject(beanName = “为myBean”) MyBeanEJBHome myBean;
在这种情况下,MyBeanEJBHome可能需要的任何标准EJB注入都可以正常工作。