是否可以在使用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;
}
}
答案 0 :(得分:1)
有两种可能的解决方案。
如果你有一个JavaEE-7容器,那么你可以使用CDI.current().get(MySingletonClass.class);
如果您有JavaEE-6容器甚至是Java SE应用程序,那么您可以使用Apache DeltaSpike BeanProvider。 它试图从JNDI查找BeanManager,但也做其他技巧,如果你没有一个完整的EE容器也可以。例如。在SE和单元测试中。
您还需要注意不仅容器已启动,而且上下文已正确激活。这通常通过ServletListener完成。如果您在EE容器中,那么他们会为您注册。如果您使用普通的tomcat,jetty等,那么您需要自己激活它。
请参阅Apache OpenWebBeans中的this example。