March 10, 2015

Obtaining a reference to a CDI managed bean

Most of the time you can inject your CDI beans using the @Inject annotation. There may be occasions when you need to access your CDI beans inside a class where you can not use @Inject, you have a couple of options.

To programmatically access a CDI managed bean, first you need to get hold of the BeanManager (analogous to the ApplicationContext in Spring), by using CDI.current() or by doing a JNDI lookup.

Using CDI.current()
BeanManager bm = CDI.current().getBeanManager();

Using JNDI:
BeanManager bm = null;
try {
    InitialContext context = new InitialContext();
    bm = (BeanManager) context.lookup("java:comp/BeanManager");
} catch (Exception e) {
    e.printStackTrace();
}

Now you have the BeanManager you can access your CDI beans by doing either a type-based lookup or a name-based lookup.

Type based:
Bean<CrudService> bean = (Bean<CrudService>) bm.getBeans(CrudService.class).iterator().next();
CreationalContext<CrudService> ctx = bm.createCreationalContext(bean);
CrudService crudService = (CrudService) bm.getReference(bean, CrudService.class, ctx);

Name-based
Bean bean = bm.getBeans("crudService").iterator().next();
CreationalContext ctx = bm.createCreationalContext(bean);
CrudService crudService = bm.getReference(bean, bean.getClass(), ctx);

When using name-based lookup, your name has to match the value you pass into your @Named annotation. If do not pass a value then it is the name of your class, in camel case. Example:
@Named("crudService")
public class CrudService {}

And a full code example using CDI.current() and type-based lookup:
BeanManager bm = CDI.current().getBeanManager();
Bean<CrudService> bean = (Bean<CrudService>) bm.getBeans(CrudService.class).iterator().next();
CreationalContext<CrudService> ctx = bm.createCreationalContext(bean);
CrudService crudService = (CrudService) bm.getReference(bean, CrudService.class, ctx);


No comments :

Post a Comment