Referencing a CDI Bean in a non managed CDI Bean

佐手、 提交于 2019-12-13 16:14:33

问题


Is it possible to obtain an instance of a CDI bean inside a class that is created using the new keyword? We're currently making some enhancements on an old application, and we're always getting a ContextNotActiveException everytime we do a programmatic lookup on CDI Singleton beans in our app.

Code for obtaining a reference:

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:


There are 2 possible solutions.

  1. If you have a JavaEE-7 container then you can use CDI.current().get(MySingletonClass.class);

  2. If you have a JavaEE-6 container or even a Java SE application then you can use Apache DeltaSpike BeanProvider. It tries to lookup the BeanManager from JNDI but also does other tricks which also work if you don't have a full EE container. E.g. in SE and unit test.

You also need to take care that not only the container got booted but also that the Contexts did properly get activated. This is usually done via a ServletListener. If you are in an EE container then they register it for you. If you are using plain tomcat, jetty, etc then you need to activate it yourself.

See this example from Apache OpenWebBeans.



来源:https://stackoverflow.com/questions/28600457/referencing-a-cdi-bean-in-a-non-managed-cdi-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!