How to programmatically inject a Java CDI managed bean into a local variable in a (static) method

自作多情 提交于 2019-11-27 04:12:42

To inject an instance of class C:

javax.enterprise.inject.spi.CDI.current().select(C.class).get()

This is available in CDI 1.1+

Use for instance this utility class. You basically have to obtain instance of BeanManager and than grab the bean you want from it (imagine something like JNDI lookup).

Update

You could also use CDI utility class offered in CDI 1.1

SomeBean bean = CDI.current().select(SomeBean.class).get();

@BRS

import javax.enterprise.inject.spi.CDI;

...

IObject iObject = CDI.current().select(IObject.class, new NamedAnnotation("iObject")).get();

With:

import javax.enterprise.util.AnnotationLiteral;

public class NamedAnnotation extends AnnotationLiteral<Named> implements Named {

     private final String value;

     public NamedAnnotation(final String value) {
         this.value = value;
     }

     public String value() {
        return value;
    }
}

The link suggested by @Petr Mensik is very useful. I am using the same code in my example.

Here is a way to get an instance of the class in instance methods/static methods. It is always better to code for interfaces instead of using the class name hard coded in the methods.

@Named(value = "iObject ")
@RequestScoped
class IObjectImpl  implements IObject  {.....}

//And in your method

IObject iObject = (IObject) ProgrammaticBeanLookup.lookup("iObject");
.........
//Invoke methods defined in the interface

This programmatic look up of beans can be quite useful when you have an application scoped object with method that requires an instance of a class that may change over time. So, it is always better to extract the interface and use programmatic bean look up for the sake of loose coupling.

You should include qualifiers:

List<Annotation> qualifierList = new ArrayList();
 for (Annotation annotation: C.class.getAnnotations()) {
   if (annotation.annotationType().isAnnotationPresent(Qualifier.class)) {
     qualifierList.add(annotation);
   }
 }
javax.enterprise.inject.spi.CDI.current()
   .select(C.class, qualifierList.toArray(new Annotation[qualifierList.size()])
   .get()
  • You could define a parameter with the type of the bean interface in your static method, and pass an appropriate implementation reference. That would make it more unit-testing friendly.
  • If you're using Apache Deltaspike, you can use BeanProvider#getContextualReference. It's easier than getting a javax.enterprise.inject.Instance, but, beware of dependent beans (see javadoc)!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!