-
Notifications
You must be signed in to change notification settings - Fork 137
Java Java CDI Beans Scopes
CDI (Contexts and Dependency Injection) is a Java specification used to manage objects and their dependencies automatically.
It is part of:
- Java EE
- Jakarta EE
CDI provides:
- Dependency Injection (DI)
- Object lifecycle management
- Scope management
- Loose coupling between components
Without CDI:
Student student = new Student();The developer manually creates objects.
With CDI:
@Inject
private Student student;The CDI container automatically creates and manages the object.
The CDI container is responsible for:
- Creating beans
- Injecting dependencies
- Managing bean lifecycle
- Destroying beans when their scope ends
A CDI Bean is a Java object whose lifecycle is managed by the CDI container.
A normal Java class becomes a CDI bean when it is discovered by CDI and contains CDI annotations.
Example:
import jakarta.inject.Named;
import jakarta.enterprise.context.RequestScoped;
@Named
@RequestScoped
public class StudentBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}Here:
-
StudentBeanis a CDI bean. - CDI creates and manages the object.
- Other classes/pages can use this bean.
A CDI bean has a lifecycle:
Bean Creation
|
Initialization
|
Usage
|
Destruction
CDI controls:
- When the object is created
- How long it stays alive
- When it is destroyed
Example:
@PostConstruct
public void initialize(){
System.out.println("Bean Created");
}
@PreDestroy
public void cleanup(){
System.out.println("Bean Destroyed");
}Executed after CDI creates the bean.
Used for:
- Loading initial data
- Initial configuration
- Database initialization
Example:
@PostConstruct
public void init(){
loadUsers();
}Executed before CDI destroys the bean.
Used for:
- Closing resources
- Cleaning data
Example:
@PreDestroy
public void destroy(){
closeConnection();
}@Named makes a CDI bean accessible from the UI layer, especially JSF/XHTML pages.
Without @Named, the bean cannot be directly accessed using Expression Language (EL).
Example:
@Named("student")
@RequestScoped
public class StudentBean {
private String name;
}Now it can be accessed in XHTML:
<h:outputText value="#{student.name}" />The name inside XHTML is: #{student}
If no name is provided:
@Named
public class StudentBean {
}CDI automatically creates the name: studentBean
because:
Class name: StudentBean
becomes: studentBean
Equivalent:
@Named("studentBean")
public class StudentBean {
}@SessionScoped creates a CDI bean that exists throughout the user's session.
The same bean instance is available across multiple pages.
Example:
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import java.io.Serializable;
@Named
@SessionScoped
public class UserBean implements Serializable {
private String username;
}The bean survives:
login.xhtml
|
dashboard.xhtml
|
profile.xhtml
|
settings.xhtml
The bean is destroyed when:
- User logs out
- Session expires
- Server invalidates session
Session data may need to be:
- Stored temporarily
- Replicated between servers
- Serialized by the application server
Therefore, @SessionScoped beans should implement Serializable.
Example:
public class UserBean implements Serializable {
}A scope defines the lifetime of a CDI bean.
It answers: How long should this bean exist?
Example:
- A search bean may only need to exist during one request.
- A logged-in user bean may need to exist until logout.
CDI provides different scopes:
| Scope | Lifetime |
|---|---|
| Request Scope | One HTTP request |
| View Scope | One JSF page |
| Session Scope | One user session |
| Application Scope | Entire application |
| Custom Scope | Developer-defined lifetime |
A request scoped bean exists only for one HTTP request.
Lifecycle:
User Request
|
Bean Created
|
Process Request
|
Bean Destroyed
Example:
@Named
@RequestScoped
public class LoginBean {
}- Login validation
- Search operations
- Temporary calculations
Example — User clicks search:
Request
|
SearchBean created
|
Search completed
|
SearchBean destroyed
- Keeping user information
- Maintaining page data
A view scoped bean exists while the user remains on the same JSF page.
It survives multiple requests from the same page.
Example:
@Named
@ViewScoped
public class EmployeeBean implements Serializable {
}Lifecycle:
Open Page
|
Create Bean
|
AJAX Requests
|
User Leaves Page
|
Destroy Bean
User opens: employees.xhtml
Bean created: EmployeeBean
User performs:
- Search
- Filter
- Sort
- Pagination
The same bean remains alive.
When user navigates:
employees.xhtml
|
v
customers.xhtml
The bean is destroyed.
- JSF forms
- Data tables
- Pagination
- AJAX based pages
A session scoped bean exists for one user session.
Lifecycle:
User Login
|
Create Bean
|
Use Multiple Pages
|
Logout
|
Destroy Bean
Example:
@Named
@SessionScoped
public class LoginSession implements Serializable {
private String username;
}Logged user information
username
role
permissionsShopping cart
cartItemsUser preferences
language
themeApplication scoped beans exist for the entire application lifetime.
Lifecycle:
Application Start
|
Bean Created
|
All Users Share Same Bean
|
Application Shutdown
|
Bean Destroyed
Example:
@Named
@ApplicationScoped
public class ConfigurationBean {
}- System configuration
- Cache data
- Global constants
- Shared lookup values
Example:
Country List
Currency List
System Settings
All users share the same object.
A custom scope allows developers to create their own bean lifecycle.
Built-in scopes may not always satisfy business requirements.
Examples:
- Conversation scope
- Tenant scope
- Workflow scope
A custom scope requires:
- Custom annotation
- Scope definition
- Context implementation
Example:
@NormalScope
@Retention(RUNTIME)
@Target({TYPE, FIELD, METHOD})
public @interface CustomScope {
}Using custom scope:
@CustomScope
@Named
public class MyBean {
}| Scope | Lifetime | Example Usage |
|---|---|---|
| RequestScoped | One request | Login validation |
| ViewScoped | One page | JSF forms |
| SessionScoped | One user session | User login |
| ApplicationScoped | Entire application | Cache/configuration |
| CustomScoped | Custom lifecycle | Special requirements |
CDI automatically provides required objects.
Example — Service:
@RequestScoped
public class PaymentService {
}Injecting service:
@Named
@RequestScoped
public class OrderBean {
@Inject
private PaymentService paymentService;
}CDI creates:
OrderBean
|
+---- PaymentService
No manual object creation is required.
Usually CDI beans use:
@Named
+
Scope Annotation
Example:
@Named("customer")
@SessionScoped
public class CustomerBean implements Serializable {
}Meaning:
- Bean name:
customer - Lifetime:
User session
Used in XHTML:
#{customer.name}| Annotation | Purpose |
|---|---|
@Named |
Makes bean accessible in XHTML |
@Inject |
Dependency injection |
@RequestScoped |
Request lifetime |
@ViewScoped |
Page lifetime |
@SessionScoped |
User lifetime |
@ApplicationScoped |
Application lifetime |
@PostConstruct |
Initialization |
@PreDestroy |
Cleanup |
Wrong:
@SessionScoped
public class SearchBean {
}Problem:
- More memory usage
- Old data remains
- Bad performance
Better:
@ViewScoped
public class SearchBean {
}Wrong:
@SessionScoped
public class UserBean {
}Correct:
@SessionScoped
public class UserBean implements Serializable {
}Wrong:
@ApplicationScoped
public class UserBean {
}Problem:
All users share the same object.
Example:
User A: username = John
User B may see: username = John
because the object is shared.
@Named
@SessionScoped
public class LoginBean implements Serializable {
private String username;
}Lifetime:
Login
|
Session
|
Logout
@Named
@ViewScoped
public class ProductSearchBean implements Serializable {
}Lifetime:
Open product page
|
Search
|
Filter
|
Leave page
@Named
@ApplicationScoped
public class ConfigBean {
}Lifetime:
Server Start
|
All Users
|
Server Shutdown
- Data is temporary
- No state needs to be maintained
Examples:
- Login validation
- Search request
- Report generation
- Working with JSF pages
- Maintaining page state
- AJAX operations
Examples:
- Data tables
- Forms
- Pagination
- Data belongs to one user
Examples:
- Logged user
- Shopping cart
- Permissions
- Data is common for everyone
Examples:
- Cache
- System settings
- Lookup data
CDI manages Java objects automatically.
The most important annotations are:
Makes a bean available in XHTML.
Lives for one request:
Request → Create → Destroy
Lives while staying on one page:
Page Open → Multiple Actions → Leave Page
Lives during user session:
Login → Multiple Pages → Logout
Lives during application lifetime:
Server Start → All Users → Server Stop
Short Lifetime
|
@RequestScoped
|
@ViewScoped
|
@SessionScoped
|
@ApplicationScoped
|
Long Lifetime
Choosing the correct CDI scope is important for:
- Performance
- Memory management
- Data isolation
- Correct application behavior
- Maintainability