1

这是一个由 Java EE 应用程序在运行时生成/加载的类(@Default Barbean 由同一应用程序提供):

public class Foo {

    @PersistenceContext private EntityManager em;
    @Resource private UserTransaction tx;
    @EJB private MyEJB ejb;
    @Inject Bar bar;

    public Foo() {
    }

    @PostConstruct
    public void postConstruct () { ... }

    public void businessMethod() { ... }

}

以下是它的实例化方式:

    import javax.enterprise.inject.spi.Unmanaged;
    ...

    @Inject private BeanManager bm;
    ...

    Class clazz = loadClazz();

    Unmanaged unmanaged = new Unmanaged(bm, clazz);

    Object obj = unmanaged.newInstance()
            .produce()
            .inject()
            .postConstruct()
            .get();

使用 JBoss/WildFly,所有字段都被正确注入,包括 EntityManager、EJB、UserTransaction 等。

使用 TomEE 和 GlassFish,Java EE 资源将被忽​​略,并且只有bar字段被注入。

  1. 这应该被认为是 TomEE 和 GlassFish 中的一个错误,还是只是 JavaEE/CDI 规范中的一个白点,在应用程序服务器中以不同的方式实现?这绝对不是纯粹的 CDI 问题,因为 GlassFish 和 WildFly 都使用相同的 CDI 实现,即JBoss Weld
  2. 如何使用 TomEE 和 GlassFish 实现上述目标?可移植的解决方案是首选,但一些依赖于服务器的代码是可以的(我担心这种问题是不可避免的)。

总体目标是为动态代码提供全方位的 CDI 注入(简单@Inject以及 Java EE 资源,如,@PersistenceContext等)。我的第一次尝试是动态生成一个包含注释字段 + 动态业务逻辑的类(是的,它有效,尽管仅在 WildFly 中)。一般来说,我有一组这样的动态注入定义:@Resource@EJB

@Annotation(param = "value") @Qualifier1 @Qualifier2 ... Type name;

, ,等中Annotation的一个在哪里,我想获得一个实例,如果它在 CDI 托管 bean 中,则该实例将被注入。因此,可以接受一种假设方法,该方法将采用注入元数据并返回相应的实例。InjectPersistenceContextResourceEJB

4

1 回答 1

0

您是否尝试过通过生产者字段声明资源

这样做,您可以在不诉诸 CDI 之前的注释的情况下使用@Inject您的EntityManager等。UserTransaction

由于 CDI 注入@Inject似乎在您的所有环境中都有效,因此这可能是一个可行的解决方案。

于 2016-03-26T20:45:06.090 回答