Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE : With CDI in place, do we ever need to use 'new' for our own POJO's

Env:

Wildfly 8.2.0 Final
JDK 8
Java EE 7

Please note that by 'POJO' i am referring to the classes that serve the other classes i.e other than value objects, entities.

This question was on back of my head for some time. Just wanted to put it out.

Based on CDI and Managed Beans specs and various other books/articles, its pretty clear that CDI injection starts with a 'managed' bean instance. By 'managed' i mean servlet, EJBs etc. which are managed by a container. From there, it injects POJOs (kind of crawl through layers) till every bean gets its dependencies. This all makes very sense to me and i see very little reason why developers ever need to use "new" to create an instance of their dependent POJO's.

  1. One scenario that comes to my mind is when developer would like to have logic similar to
if(something) { 
 use-heavy-weight-A-instance
} else {
 use-heavy-weight-B-instance
}

But, that also can be achieved via @Produces.

  1. Here is one scenario that i verified to be true in wildfly 8.2.0 Final i.e. CDI is not able to inject bean when the JSP has
<%!
  @Inject
  BeanIntf bean;
%>

But, the alternative to use a servlet works fine.

That said, would like to know if there is any scenario(s) where a developer has to use 'new'. As i understand, by using 'new', developer owns the responsibility of fulfilling dependencies into that bean and all its dependent beans, and their dependent beans etc..

Thanks in advance,

Rakesh

like image 466
Rakesh Kumar Cherukuri Avatar asked Dec 20 '25 01:12

Rakesh Kumar Cherukuri


1 Answers

When using CDI or other container you don't use new, because you expect a bunch of service coming from the container.

For CDI these main services are:

  • Injection of dependent beans (get existing instance or create a new instance)
  • Lifecycle callback management (@PostConstruct and @PreDestroy)
  • Lifecycle management of your instance (a @RequestScoped bean will make container produce an instance leaving until the end of request)
  • Applying interceptors and decorators on your instance
  • Registering and managing observers methods
  • Registering and managing producers methods

Now, on some rare occasion, you may want to add a part of these services to a class you instantiate yourself (or that another framework like JPA instantiate for you).

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

AnnotatedType<MyClass> type = bm.createAnnotatedType(MyClass.class);
InjectionTarget<MyClass> it = bm.getInjectionTargetFactory(type).createInjectionTarget(null);
CreationalContext<MyClass> ctx = bm.createCreationalContext(null);

MyClass pojo = new MyClass();
injectionTarget.inject(instance, ctx); // will try to satisfied injection points 
injectionTarget.postConstruct(instance); // will call @PostConstruct

With this code you can instantiate your own MyClass containing injection points (@Inject) and lifecycle callbacks (@PostConstruct) and having these two services honored by the container. This feature is used by 3rd party frameworks needing a basic integration with CDI.

The Unmanaged class handle this for you, but still prevent you to do the instantiation ;).

like image 174
Antoine Sabot-Durand Avatar answered Dec 22 '25 15:12

Antoine Sabot-Durand