Are CDI.current().select().get() and BeanManager.getReference() functionally equivalent?

Viewed 5750

In the context of JEE/CDI, I find myself typically using a CDI static function when I need to retrieve a CDI managed bean statically from a method. For instance:

MyBean myBean = CDI.current().select( MyBean.class ).get()

However, from what I can tell, another equivalent way to accomplish this is using the BeanManager:

BeanManger bm = new InitialContext().lookup( "java:comp/BeanManager" );
Bean<?> bean = bm.resolve(bm.getBeans( MyBean.class ) );
CreationalContext<?> context = bm.createCreationalContext(bean);
MyBean myBean = bm.getReference(bean, cls, context);

So other than being significantly less code to write using the CDI.current() method, what differences are there in using it? It would seem that reverting to using the BeanManager is a much more complex (and potentially error prone?) methodology. From a functional perspective, are there any drawbacks in using the CDI.current() method instead? Does CDI...select() only work for an @ApplicationScope bean? Or can I use with other scoped beans (ex: @Dependent) as well?

I remember reading something about potentially memory leaks using the CDI method, but do not understand how or why this could be the case.

2 Answers

Both approaches yield similar result however, there are two major differences differences.

  • CDI.current() is something you can you where you cannot simply @Inject BeanManager.
    • It is just a way to get hold of CDI instances from a non-cdi managed object
  • Instance.get() doesn't take a CreationalContext parameter whereas BM.getReference() does.
    • This is crucial difference in a way that when using Instance, the CreationalContext is managed by container - you needn't care about it and especially about releasing the context. If you are using BM.getReference() you firstly need to obtain that context which usually means creating it and that holds you responsible to also release it once you are done working with it.

We use these methods for accessing CDI in your non-CDI code. in CDI code we could inject BeanManager and your beans.

JNDI lookup is used in CDI 1.0. after CDI 1.1 we should use CDI class and its static methods.

http://www.next-presso.com/2016/02/cdi-the-spi-who-loved-me/ says

In CDI 1.0 the only solution you had to access CDI bean graph was to retrieve the BeanManager from JNDI ... This verbosity is the proof that the BeanManager is and advanced CDI tool allowing very basic operation on CDI echos system. It’s obviously not the best solution if you just want to access an instance. That’s why, in CDI 1.1 we introduced the abstract CDI class which use Java Service Loader to retrieve a concrete CDI class from the implementation. ... Retrieving an instance becomes as simple as

CDI<Object> cdi = CDI.current();
MyService service = cdi.select(MyService.class).get();
Related