How can I programmatically inject a Java CDI 1.1+ managed bean into a local variable in a static method?
6 Answers
To inject an instance of class C
:
javax.enterprise.inject.spi.CDI.current().select(C.class).get()
This is available in CDI 1.1+

- 4,070
- 3
- 30
- 54
-
10If you use CDI.current().select, you'll get an Instance
, don't forget to destroy it after using it. – jpangamarca May 12 '15 at 14:00 -
XDR, Your solution is working for me. I was trying a different way but couldn't get it working: context.getApplication().evaluateExpressionGet(context, "#{beanName}", BeanName.class) shouldn't they both work? – TigerBear Oct 13 '15 at 19:58
-
@punchingInAPepper: I'm unfamiliar with the method that you mentioned, so, unfortunately, I can't answer your question. – XDR Oct 14 '15 at 08:02
-
@XDR No worries, just thought it wouldn't hurt to ask. After searching for hours, this was the only solution that worked, It would be nice if there was more info on why. Do you have links to resources that helped you figure this out? – TigerBear Oct 14 '15 at 17:54
-
@punchingInAPepper: I forget where I learned this. It might have been from the weld documentation: https://docs.jboss.org/weld/reference/latest/en-US/html/ – XDR Oct 15 '15 at 01:59
-
1@jpangamarca destroy? Can you explain how? – Dherik Aug 15 '17 at 13:15
-
@jpangamarca maybe means `null`-ing it? Mostly you want to keep an instance of your backing bean (`get()` returned it) in your converter/validator for performance reasons (please look at the source code of `CDI`'s methods). I usually do this with a static field in the converter/validator: `private static MyFooBackingBean FOO_CONTROLLER;` and later: `if (null == FOO_CONTROLLER) { FOO_CONTROLLER = CDI.current().select(MyFooBackingBean.class).get(); }` Maybe annotations are missing here. – Roland Nov 02 '17 at 11:11
-
2@Dherik Destroying a bean reference obtained from an injected Instance
is necessary to avoid memory leaks, please see http://weld.cdi-spec.org/news/2016/05/18/enhanced-instance/ – jpangamarca Nov 06 '17 at 15:01 -
@XDR Thanks for the solution does this work with cdi2.0 ? i'm getting weld not initialized – user2359997 Sep 24 '19 at 18:38
-
@user2359997 I haven't used CDI 2.0, but I imagine it should be backwards compatible with 1.1. I don't know about your weld issue, and I haven't used CDI or Java EE in years – XDR Sep 26 '19 at 11:12
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.

- 26,874
- 17
- 90
- 115
-
Thanks for the suggestion. I actually found a simpler solution, which I'll detail in an answering post. – XDR Jul 20 '14 at 16:28
-
@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,070
- 3
- 30
- 54
-
So, after writing an implementation class for IObject with Named annotation value iObject, we need to write an anonymous inner class to get an instance. Isn't this a bit more complicated than by simply look up and cast? Or please correct me if my understanding is wrong. – phoenix Jan 04 '15 at 21:13
-
1Probably it would be the better if you can actually make it more readable by having the import and dividing one step into two steps. That way it becomes more readable. – phoenix Jan 04 '15 at 21:19
-
`NamedAnnotation` can be used for any `@Named` bean, not just `IObject`s. `ProgrammaticBeanLookup` takes more code than `NamedAnnotation`, but can only be used for `Class` or `@Named String`, whereas the `CDI` route can take in other annotations and/or a `TypeLiteral`. `ProgrammaticBeanLookup` also requires JNDI classes to be in the classpath, and manual population of a non-final static variable if it isn't. Moreover, `BeanManager` isn't guaranteed to be threadsafe, so `ProgrammaticBeanLookup` might have threading issues. – XDR Jan 04 '15 at 21:45
-
You can always wrap the `CDI` usage in a helper method, such as `
T getNamedBean(Class – XDR Jan 04 '15 at 21:46clazz, String name)`
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.

- 985
- 3
- 17
- 38
-
Please see my new answer that shows how annotations can be used with the `CDI` methodology, which provides more versatile and typesafe lookups than `ProgrammaticBeanLookup` – XDR Jan 04 '15 at 20:58
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()

- 36
- 5
- 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)!

- 713
- 2
- 13
- 33