仅获取服务中的CDI管理的Bean [英] Get only in-service CDI managed beans
问题描述
我的目标是从JSF2 ExceptionHandlerWrapper中获取所有在服务CDI托管的Bean(属于某个父类)的集合.请注意,异常处理程序部分很重要,因为该类本身不是有效的注入目标.因此,我的假设(可能不正确)是我唯一的路由是通过BeanManager进行编程的.
My goal is to get a collection of all in-service CDI managed beans (of a certain parent class) from within a JSF2 ExceptionHandlerWrapper. Note the exception handler part is significant because the class is not a valid injection target itself. So my assumption (maybe incorrect) is that my only route is programmatic through BeanManager.
使用BeanManager.getBeans,我可以成功获取所有可用于注入的bean的集合.我的问题是,当使用BeanManager.getReference获取Bean的上下文实例时,将创建该Bean(如果尚不存在).因此,我正在寻找仅返回实例化bean的替代方法.下面的代码是我的出发点
Using BeanManager.getBeans, I can successfully get the set of all beans available for injection. My issue is that when using BeanManager.getReference to obtain the contextual instance of the bean, the bean will be created if it does not already exist. So I am looking for an alternative that will only return instantiated beans. The code below is my starting point
public List<Object> getAllWeldBeans() throws NamingException {
//Get the Weld BeanManager
InitialContext initialContext = new InitialContext();
BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");
//List all CDI Managed Beans and their EL-accessible name
Set<Bean<?>> beans = bm.getBeans(AbstractBean.class, new AnnotationLiteral<Any>() {});
List<Object> beanInstances = new ArrayList<Object>();
for (Bean bean : beans) {
CreationalContext cc = bm.createCreationalContext(bean);
//Instantiates bean if not already in-service (undesirable)
Object beanInstance = bm.getReference(bean, bean.getBeanClass(), cc);
beanInstances.add(beanInstance);
}
return beanInstances;
}
推荐答案
Here we are...poking through the javadoc I found Context which has two versions of a get() method for bean instances. One of them, when passing in a creational context, has the same behavior as BeanManager.getReference(). However the other just takes a Bean reference and returns either the contextual instance (if available) or else null.
利用它,这是原始方法的版本,该方法仅返回实例化的bean:
Leveraging that, here is the version of the original method which returns only instantiated beans:
public List<Object> getAllCDIBeans() throws NamingException {
//Get the BeanManager via JNDI
InitialContext initialContext = new InitialContext();
BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");
//Get all CDI Managed Bean types
Set<Bean<?>> beans = bm.getBeans(Object.class, new AnnotationLiteral<Any>() {});
List<Object> beanInstances = new ArrayList<Object>();
for (Bean bean : beans) {
CreationalContext cc = bm.createCreationalContext(bean);
//Get a reference to the Context for the scope of the Bean
Context beanScopeContext = bm.getContext(bean.getScope());
//Get a reference to the instantiated bean, or null if none exists
Object beanInstance = beanScopeContext.get(bean);
if(beanInstance != null){
beanInstances.add(beanInstance);
}
}
return beanInstances;
}
这篇关于仅获取服务中的CDI管理的Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!