2013-11-15 10 views
6

Mein Ziel ist es, eine Sammlung aller CDI-verwalteten Beans im Betrieb (einer bestimmten Elternklasse) aus einem JSF2-ExceptionHandlerWrapper zu erhalten. Beachten Sie, dass der Exception-Handler-Teil von Bedeutung ist, da die Klasse selbst kein gültiges Injektionsziel ist. Meine Annahme (vielleicht inkorrekt) ist, dass meine einzige Route programmatisch durch BeanManager ist.Nur CDI-verwaltete Beans im Betrieb abrufen

Mit BeanManager.getBeans kann ich die Menge aller für die Injektion verfügbaren Beans erfolgreich erhalten. Mein Problem ist, dass wenn BeanManager.getReference verwendet wird, um die kontextabhängige Instanz der Bean zu erhalten, die Bean erstellt wird, wenn sie nicht bereits existiert. Also suche ich nach einer Alternative, die nur instanziierte Bohnen zurückgibt. Der folgende Code ist mein Ausgangspunkt

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; 
} 

Antwort

7

Hier sind wir ... Stossen durch die javadoc ich Context gefunden, die für die Bean-Instanzen zwei Versionen eines get() Methode hat. Einer von ihnen, wenn er in einem schöpferischen Kontext übergeben wird, hat das gleiche Verhalten wie BeanManager.getReference(). Der andere verwendet jedoch nur eine Bean-Referenz und gibt entweder die kontextabhängige Instanz (falls verfügbar) oder sonst null zurück.

dass Nutzung, hier ist die Version der ursprünglichen Methode, die nur instanziiert Bohnen zurückgibt:

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; 
}