Вот класс, который генерируется/загружается во время выполнения приложением Java EE (бин @Default Bar
предоставляется тем же приложением):
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
, @Resource
, @EJB
и т. д.) в динамический код. Моя первая попытка состояла в том, чтобы сгенерировать класс на лету, который включал бы аннотированные поля + динамическую бизнес-логику (и да, это сработало, хотя и только в WildFly). Вообще говоря, у меня есть набор определений динамических инъекций, например:
@Annotation(param = "value") @Qualifier1 @Qualifier2 ... Type name;
где Annotation
является одним из Inject
, PersistenceContext
, Resource
, EJB
и т. д., и я хочу получить экземпляр, который был бы внедрен, если бы он находился внутри управляемого компонента CDI. Таким образом, допустим гипотетический метод, который будет принимать метаданные инъекции и возвращать соответствующий экземпляр.