在非托管CDI Bean中引用CDI Bean

时间:2015-02-19 07:06:49

标签: java cdi java-ee-6 openwebbeans

是否可以在使用new关键字创建的类中获取CDI bean的实例?我们目前正在对旧应用程序进行一些增强,每当我们在应用程序中对CDI Singleton bean进行ContextNotActiveException查找时,我们总是得到programmatic

获取参考的代码:

public class ClassCreatedWithNew{
     public void doSomething(){
         MySingletonBean myBean = BeanManagerSupport.getInstance().getBean(MySingletonBean.class);
     }
}

BeanManagerSupport.java

public class BeanManagerSupport {

    private static final Logger LOG = Logger.getLogger(BeanManagerSupport.class);

    private static final BeanManagerSupport beanManagerSupport = new BeanManagerSupport();

    private BeanManager beanManager;

    private BeanManagerSupport() {
        try {
            beanManager = InitialContext.doLookup("java:comp/BeanManager");
        } catch (NamingException e) {
            LOG.error("An error has occured while obtaining an instance of BeanManager", e);
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getBean(Class<T> clazz) {
        Iterator<Bean< ? >> iter = beanManager.getBeans(clazz).iterator();

        if (!iter.hasNext()) {
            throw new IllegalStateException("CDI BeanManager cannot find an instance of requested type " + clazz.getName());
        }

        Bean<T> bean = (Bean<T>) iter.next();

        return (T) beanManager.getContext(bean.getScope()).get(bean);
    }

    public static BeanManagerSupport getInstance(){
        return beanManagerSupport;
    }
}

1 个答案:

答案 0 :(得分:1)

有两种可能的解决方案。

  1. 如果你有一个JavaEE-7容器,那么你可以使用CDI.current().get(MySingletonClass.class);

  2. 如果您有JavaEE-6容器甚至是Java SE应用程序,那么您可以使用Apache DeltaSpike BeanProvider。 它试图从JNDI查找BeanManager,但也做其他技巧,如果你没有一个完整的EE容器也可以。例如。在SE和单元测试中。

  3. 您还需要注意不仅容器已启动,而且上下文已正确激活。这通常通过ServletListener完成。如果您在EE容器中,那么他们会为您注册。如果您使用普通的tomcat,jetty等,那么您需要自己激活它。

    请参阅Apache OpenWebBeans中的this example