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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With