当通过ResourceContext获取子资源时,将EJB注入JAX-RS 2.0子资源

时间:2014-05-15 15:23:46

标签: glassfish ejb jax-rs jersey-2.0

我正在使用带有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无法完成它的工作。这是对的吗?

1 个答案:

答案 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注入都可以正常工作。