Java EE CDI - 生成带有注入字段的bean

时间:2014-11-26 11:17:35

标签: java java-ee cdi

因为我有一些需要传递给新生成的对象的泛型,我正在创建一个生成器。但是当生产者工作时,EntityManager不会被注入,因为生成器使用运算符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服务,否则会正确注入

欢迎对代码提出任何改进建议。谢谢!

1 个答案:

答案 0 :(得分:1)

你混合了很多无关的东西:

  1. 您的服务MultiselectorService是一个EJB,您无法使用生产者生成它。创建应用程序后注册EJB,然后根据创建实例的范围进行注册。

  2. 你有一个方法public void MultiselectorService(Class<? extends Dbo> clazz),其名称类似于构造函数,它违反了约定。

  3. 假设你已经修复了那个方法作为构造函数,但是然后行'itemList = em.createQuery(“some Sql String”,clazz);' NPE会失败。因为只有在创建bean之后才会初始化em。有两种方法可以做到:

    • 将实体管理器注入构造函数(这是针对EJB规范的,如果您仍将使用EJB)

    • 在带注释'@PostConstruct'的方法中执行初始化操作

  4. 您有EntityManager的制作人吗?例如你不能只注入实体管理器,你需要提供作为EJB的资源,注释@PersistenceContext

  5. 我明白你想要实现的目标。主要问题是手动创建的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);
         }
      }
    

    并注入SpecialDboMultiselectorService