【问题标题】:Inject EJB into JAX-RS 2.0 subresource when subresource is got via ResourceContext当通过 ResourceContext 获取子资源时,将 EJB 注入 JAX-RS 2.0 子资源
【发布时间】:2014-05-15 15:23:46
【问题描述】:

我正在使用带有 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 没有注入其中。

以前我使用带有专有 ResourceContext 的 Glassfish 3 和 Jersey 1.17,并且完全相同的代码可以正常工作。

我搜索了很多并阅读了很多类似(但有点不同)的问题,据我了解,当通过 ResorceContext 获取子资源时,无法注入非 JAX-RS 内容(在我的情况下为 EJB)。这是真的吗?如果是,我该如何解决? 一种可能的解决方案是将子资源对象注入资源定位器类,但是它们太多了,看起来很丑。

EDIT 如果要创建一个活页夹,将 ejb 类绑定到 ejb 接口并注册该活页夹,则使用 @Inject 进行注入有效。但我不想描述我的数百个 ejb 的绑定。另外据我了解,它是特定的绑定杉木 HK2 系统,我不想与之链接。

设置 @Named 注释和尝试通过 CDI 注入的不同操作没有帮助。似乎当通过 ResourceContext Jersey 获取子资源时只使用 HK2,这就是 CDI 无法做到这一点的原因。对吗?

【问题讨论】:

    标签: glassfish ejb jax-rs jersey-2.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 注入也可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 2019-03-01
      相关资源
      最近更新 更多