I figured that there are two general ways to obtain an auto-created CDI managed bean instance via BeanManager
when having solely a Bean<T>
to start with (which is created based on Class<T>
):
By
BeanManager#getReference()
, which is more often shown in snippets:Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class)); TestBean testBean1 = (TestBean) beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));
By
Context#get()
, which is less often shown in snippets:Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class)); TestBean testBean2 = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean));
In effects, they do ultimately exactly the same thing: returning a proxied reference to the current CDI managed bean instance and auto-creates the bean instance if it doesn't already exist in the scope.
But they do it a bit differently: the BeanManager#getReference()
always creates a whole new proxy instance, while the Context#get()
reuses an existing proxy instance if already created before. This is evident when the above code is executed in an action method of an existing TestBean
instance:
System.out.println(testBean1 == testBean2); // false
System.out.println(testBean1 == this); // false
System.out.println(testBean2 == this); // true
The javadoc of Context#get()
is very explicit in this:
Return an existing instance of certain contextual type or create a new instance by calling Contextual.create(CreationalContext) and return the new instance.
while the javadoc of BeanManager#getReference()
is not explicit enough on this:
Obtains a contextual reference for a certain bean and a certain bean type of the bean.
This got me confused. When do you use the one or the other? For the both ways you need a Bean<T>
instance anyway, from which the bean class and bean scope is readily available which is required as additional argument. I can't imagine why they would need to be supplied externally in this specific case.
I can imagine that Context#get()
is more memory efficient as it doesn't unnecessarily create another proxy instance referring the very same underlying bean instance, but just finds and reuses an existing proxy instance.
This puts me to the following question: when exactly is the BeanManager#getReference()
more useful than Context#get()
? It's more often shown in snippets and more often recommended as solution, but it only unnecessarily creates a new proxy even when one already exists.