问题
How can I programmatically inject a Java CDI 1.1+ managed bean into a local variable in a static method?
回答1:
To inject an instance of class C
:
javax.enterprise.inject.spi.CDI.current().select(C.class).get()
This is available in CDI 1.1+
回答2:
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();
Update 2
In CDI 2.0 you have to use BeanManager class for obtaining bean instances programatically.
回答3:
@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;
}
}
回答4:
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.
回答5:
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()
回答6:
- 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)!
来源:https://stackoverflow.com/questions/24798529/how-to-programmatically-inject-a-java-cdi-managed-bean-into-a-local-variable-in