Java EE CDI bean scopes
When a managed bean is initialized by CDI the bean will be initialized in a very specific scope. The scope in which the bean is initialized will determine its lifecycle. CDI provides the following bean scopes:
|ApplicationScoped||When a bean scope is defined as ApplicationScoped this means that only one instance of the bean will exist in the entire application. After bean initialization, every time a client requests an instance of this bean the container will always provide the same bean instance.|
|SessionScoped||SessionScoped beans are to be used inside a web application context. When a bean is configured as SessionScoped this means that an instance of this bean will exist per HTTP session.|
|RequestScoped||RequestScoped beans are to be used inside a web application context. When a bean is configured as RequestScoped this means that an instance of this bean will exist per HTTP request.|
|ConversationScoped||ConversationScoped beans are to be used inside a web application context. As the name states, this kind of beans are used to represent a conversation between the client and the server. They may be used to keep state between multiple client AJAX requests or even between distinct page requests, if the client provides the conversation identifier to the server between page requests.|
CDI also provides two additional pseudo-scopes:
|Singleton||As the name states, a Singleton bean represents a singleton so it will only exist one instance of a bean configured as Singleton.|
|Dependent||Dependent scope beans will be assigned the same scope as the bean they are being injected into, ie. if a Dependent scoped bean is injected into a SessionScoped bean, the injected bean will also be configured as SessionScoped and will exist until the current HTTP session exists.|
When a CDI managed bean is injected into another bean, the CDI container will not pass a reference to the injected bean itself but will instead pass a reference to a proxy. This proxy will handle all the calls made by the client to the injected bean transparently.
Consider a SessionScoped bean: If distinct HTTP sessions request a SessionScoped bean instance they will all be provided with the same proxy instance. When they make calls to the injected bean through the proxy, the proxy will know how to fetch the correct bean instance and then provide it to each HTTP session respectively.
Managed CDI beans that are able to live for longer periods of time, such as SessionScoped and ConversationScoped, must implement the Serializable interface. This is because the container may need to free resources for an arbitrary reason and it may decide to persist a bean of this type into physical storage (or other persistent media type). When the persisted bean is once again needed for correct application execution, the container will fetch the bean and restore its state.
The Singleton pseudo-scope
When Singleton scoped beans are injected into client beans, the client beans will get a direct reference to the injected bean. This means that if the client bean is Serializable (ex: SessionScoped or ConversationScoped) it must also take care of the correct injected Singleton bean serialization. There are ways to assure that the injected bean remains a true singleton:
- Implement writeReplace() and readResolve() in the Singleton bean as specified by the standard Java serialization
- Make the reference to the Singleton bean transient. When the client bean is de-serialized by the container, the container will inject again the reference to the Singleton scoped bean.
The Dependent pseudo-scope
Dependent scope is the default CDI bean scope, ie. if a bean does not declare a specific scope it will be injected as a Dependent scoped bean. This means that it will have the same scope as the bean where it's being injected. Dependent scoped bean instances are never shared between clients. Every client will always fetch a new instance of a Dependent scoped bean.
Where is the View scope?
If you are familiar with JSF bean scopes you may be wondering where does the ViewScoped bean type fits into this model. CDI does not offer any View scope but provides ConversationScoped beans instead.
With ConversationScoped beans we achieve the same functionality one usually needs from a View scoped JSF bean (maintain bean state between AJAX requests) and even more: it is possible to maintain the same conversation - or state - between distinct page requests.
- Apache DeltaSpike (former Seam-Faces)
- ViewAccessScope beans from MyFaces CODI
We will see ConversationScoped beans in detail on another tutorial.