Java Java CDI Beans Scopes - hmislk/hmis GitHub Wiki
Java CDI Beans and Scopes
1. Introduction to CDI (Contexts and Dependency Injection)
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
2. What is a CDI Bean?
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.
3. CDI Bean Lifecycle
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");
}
@PostConstruct
Executed after CDI creates the bean.
Used for:
- Loading initial data
- Initial configuration
- Database initialization
Example:
@PostConstruct
public void init(){
loadUsers();
}
@PreDestroy
Executed before CDI destroys the bean.
Used for:
- Closing resources
- Cleaning data
Example:
@PreDestroy
public void destroy(){
closeConnection();
}
4. @Named Annotation
What is @Named?
@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}
5. Default Name of @Named Bean
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 {
}
6. @SessionScoped Annotation
What is @SessionScoped?
@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
7. Why SessionScoped Requires Serializable?
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 {
}
8. What is Scope?
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 |
9. @RequestScoped
Definition
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 {
}
Suitable For:
- Login validation
- Search operations
- Temporary calculations
Example — User clicks search:
Request
|
SearchBean created
|
Search completed
|
SearchBean destroyed
Not Suitable For:
- Keeping user information
- Maintaining page data
10. @ViewScoped
Definition
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
Example
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.
Common Uses:
- JSF forms
- Data tables
- Pagination
- AJAX based pages
11. @SessionScoped
Definition
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;
}
Common Uses:
Logged user information
username
role
permissions
Shopping cart
cartItems
User preferences
language
theme
12. @ApplicationScoped
Definition
Application 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 {
}
Common Uses:
- System configuration
- Cache data
- Global constants
- Shared lookup values
Example:
Country List
Currency List
System Settings
All users share the same object.
13. Custom Scope
What is Custom Scope?
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 {
}
14. Scope Comparison Table
| 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 |
15. Dependency Injection with CDI
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.
16. Combining @Named and Scope
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}
17. Important CDI Annotations
| 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 |
18. Common Mistakes
Mistake 1: Using SessionScoped Everywhere
Wrong:
@SessionScoped
public class SearchBean {
}
Problem:
- More memory usage
- Old data remains
- Bad performance
Better:
@ViewScoped
public class SearchBean {
}
Mistake 2: Forgetting Serializable
Wrong:
@SessionScoped
public class UserBean {
}
Correct:
@SessionScoped
public class UserBean implements Serializable {
}
Mistake 3: Using ApplicationScoped for User Data
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.
19. Real World Examples
Login System
@Named
@SessionScoped
public class LoginBean implements Serializable {
private String username;
}
Lifetime:
Login
|
Session
|
Logout
Product Search
@Named
@ViewScoped
public class ProductSearchBean implements Serializable {
}
Lifetime:
Open product page
|
Search
|
Filter
|
Leave page
System Configuration
@Named
@ApplicationScoped
public class ConfigBean {
}
Lifetime:
Server Start
|
All Users
|
Server Shutdown
20. How to Choose the Correct Scope?
Use RequestScoped when:
- Data is temporary
- No state needs to be maintained
Examples:
- Login validation
- Search request
- Report generation
Use ViewScoped when:
- Working with JSF pages
- Maintaining page state
- AJAX operations
Examples:
- Data tables
- Forms
- Pagination
Use SessionScoped when:
- Data belongs to one user
Examples:
- Logged user
- Shopping cart
- Permissions
Use ApplicationScoped when:
- Data is common for everyone
Examples:
- Cache
- System settings
- Lookup data
21. Final Summary
CDI manages Java objects automatically.
The most important annotations are:
@Named
Makes a bean available in XHTML.
@RequestScoped
Lives for one request:
Request → Create → Destroy
@ViewScoped
Lives while staying on one page:
Page Open → Multiple Actions → Leave Page
@SessionScoped
Lives during user session:
Login → Multiple Pages → Logout
@ApplicationScoped
Lives during application lifetime:
Server Start → All Users → Server Stop
Scope Selection Rule
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