因为我有一些泛型需要传递给新生成的对象,所以我正在创建一个生产者。但是,当生产者工作时,EntityManager
不会被注入(inject),因为生产者使用运算符 new
创建实例,而不是使用 CDI。
如何生成支持 CDI 的对象?
代码:
预选赛:
@Qualifier
@Retention(RUNTIME)
@Target(
{ FIELD, TYPE, METHOD })
public @interface Multiselector
{
Class<? extends Dbo> clazz();
}
制作人:
@SessionScoped
public class MultiselectorProducer implements Serializable
{
@Produces
@Multiselector(clazz = SpecialDbo.class)
public MultiselectorService<SpecialDbo> produce()
{
return new MultiselectorService<SpecialDbo>(SpecialDbo.class);
}
}
服务等级:
@Stateful
@LocalBean
public class MultiselectorService<T extends Dbo> implements Serializable
{
@Inject
private EntityManager em;
private List<T> itemList;
public MultiselectorService()
{
}
public MultiselectorService(Class<? extends Dbo> clazz)
{
itemList = em.createQuery("some Sql String", clazz);
}
....
}
注意:EntityManager
是一个自定义的 CRUD 服务,否则可以正确注入(inject)
欢迎对代码提出任何改进建议。谢谢!
最佳答案
你混合了很多不相关的东西:
您的服务
MultiselectorService
是一个 EJB,并且您不能使用生产者来生产它。创建应用程序后,EJB 就会注册,然后根据它创建实例的范围。你有一个方法
public void MultiselectorService(Class<? extends Dbo> clazz)
其名称与构造函数类似,违反惯例。假设您已将该方法固定为构造函数,但随后行 'itemList = em.createQuery("some Sql String", clazz);'会因 NPE 失败。因为
em
仅在 bean 创建后才会初始化。有两种方法可以做到这一点:将实体管理器注入(inject)到构造函数中(如果您仍将使用 EJB,这违反了 EJB 规范)
在带有注解“@PostConstruct”的方法中执行初始化操作
你有
EntityManager
的制作人吗? ?例如您不能只注入(inject)实体管理器,您需要提供 EJB 资源,并带有注释@PersistenceContext
我理解您想要实现的目标。主要问题是手动创建的 bean 不受容器管理,这意味着拦截器和装饰器将不适用(例如 PostConstruct 和 Transactional 注释将不起作用)。检查here 。到目前为止,实现这一目标的最佳方法是:
public interface SpecialDboMultiselectorService extends MultiselectorService {
}
@Stateless
public class SpecialDboMultiselectorServiceImpl extends MultiselectorServiceImpl<SpecialDbo> implements SpecialDboMultiselectorService
{
public SpecialDboMultiselectorServiceImpl() {
super(SpecialDbo.class);
}
}
public class MultiselectorServiceImpl<T extends Dbo> implements MultiselectorService {
@Inject
private EntityManager em;
private Class<? extends Dbo> clazz;
private List<T> itemList;
public MultiselectorService(Class<? extends Dbo> clazz) {
this.clazz = clazz
}
@PostConstruct
public void init() {
itemList = em.createQuery("some Sql String", clazz);
}
}
并注入(inject)SpecialDboMultiselectorService
.
关于Java EE CDI - 生成带有注入(inject)字段的 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27147760/