ApplicationScoped beans in Java EE with CDI

679 Views Asked by At

When the ApplicationScoped beans will be created ? At injection points or when application will be deployed ?

1

There are 1 best solutions below

4
Jonathan S. Fisher On

ApplicationScoped beans are lazily created, like all CDI beans. They are physically created when used. **see edit below

However, validation of injection points happens at boot time by construction a graph and ensuring said graph does not violate any of the rules in the CDI specification.

Remember that all injection points are actually injected with a proxy bean. A proxy bean is nothing but a subclass of the actual class, that was dynamically defined in the JVM when it booted. When you invoke a function on the proxy, it then finds or creates the actual instance of the bean and then routes your invocation to the bean in the background.

The whole process is pretty fascinating, and it's worth exploring with your debugger. You can set a breakpoint in the constructor of your ApplicationScoped bean and walk up the call stack to your invocation point to see what's happening.

You can force Eager init of an ApplicationScoped bean with the following:

@ApplicationScoped
public class MyService {

  void init(@Observes @Initialized(ApplicationScoped.class) Object event) {
// noop
  }
}

EDIT

**: While the statement is true, there are several surprising cases in which the scope becomes active and my answer was not fully complete... but hey we're all here to learn. @ApplicationScoped beans are indeed lazy, but in practical terms they'll probably behave as if they're initialized immediately.

It turns out the container activates the ApplicationScoped context in several surprising cases. I went and read Section 20.3.3. Application context lifecycle in Java EE of the CDI 2.0 Spec:

The application scope is active:

* during the service() method of any servlet in the web application, 
* during the doFilter() method of any servlet filter and when the container calls any ServletContextListener, HttpSessionListener, AsyncListener or ServletRequestListener,
* during any Java EE web service invocation,
* during any remote method invocation of any EJB,
* during any asynchronous method invocation of any EJB,
* during any call to an EJB timeout method and during message delivery to any EJB message-driven bean,
* when the disposer method or @PreDestroy callback of any bean with any normal scope other than @ApplicationScoped is called, and
* during @PostConstruct callback of any bean.

In addition, you may actually see your constructor invoked twice. The creation of a proxy is not explicitly forbidden to invoke the constructor of a class as far as I read in the CDI 2.0 spec.

My original source was here: https://www.cdi-spec.org/faq/

A CDI implementation may choose to lazily instantiate a normal scoped bean.