这是一个由 Java EE 应用程序在运行时生成/加载的类(@Default Bar
bean 由同一应用程序提供):
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
字段被注入。
- 这应该被认为是 TomEE 和 GlassFish 中的一个错误,还是只是 JavaEE/CDI 规范中的一个白点,在应用程序服务器中以不同的方式实现?这绝对不是纯粹的 CDI 问题,因为 GlassFish 和 WildFly 都使用相同的 CDI 实现,即JBoss Weld;
- 如何使用 TomEE 和 GlassFish 实现上述目标?可移植的解决方案是首选,但一些依赖于服务器的代码是可以的(我担心这种问题是不可避免的)。
总体目标是为动态代码提供全方位的 CDI 注入(简单@Inject
以及 Java EE 资源,如,@PersistenceContext
等)。我的第一次尝试是动态生成一个包含注释字段 + 动态业务逻辑的类(是的,它有效,尽管仅在 WildFly 中)。一般来说,我有一组这样的动态注入定义:@Resource
@EJB
@Annotation(param = "value") @Qualifier1 @Qualifier2 ... Type name;
, ,等中Annotation
的一个在哪里,我想获得一个实例,如果它在 CDI 托管 bean 中,则该实例将被注入。因此,可以接受一种假设方法,该方法将采用注入元数据并返回相应的实例。Inject
PersistenceContext
Resource
EJB