Jakarta Context Dependency Injection (CDI) is a powerful feature of the Jakarta EE platform that facilitates the management of dependencies between components, thus promoting loose coupling and enhancing testability and maintainability of applications
Dependency injection
A technique to supply a class's dependencies, usually through a constructor, attribute, or a method such as a setter
Purpose of Jakarta CDI
To allow the management of stateful or stateless component life control via context and component injection
@ApplicationScoped
Indicates a bean is managed by the CDI container and there will be a single instance of this bean for the entire application's lifecycle
@Inject
CDI will inject an instance of the annotated bean when the class is created, ensuring dependency management
Core Concepts of CDI
Dependency Injection (DI)
Managed Beans
Contexts
Type-safe Injection
Interceptors
Events
Decorators
Dependency Injection (DI)
The container supplies dependencies to an object, instead of objects creating their own dependencies, making the system more modular and decoupled
Managed Beans
The central components that are managed by the CDI container, can have different scopes like @RequestScoped, @SessionScoped, @ApplicationScoped, and custom scopes
Contexts
Refer to the lifecycle and state of a bean within a particular scope, allowing beans to be bound to the lifecycle of an application, request, session, etc.
Type-safe Injection
Beans are injected based on their type, allowing the compiler to check the correctness of injection points at compile time
Interceptors
Allow developers to encapsulate cross-cutting concerns (such as logging, transaction management, security checks) away from business logic
Events
Provide a type-safe event notification model that allows beans to communicate through the firing of events, supporting both synchronous and asynchronous event delivery
Decorators
Used to add or modify the behavior of business logic in a loosely coupled way, implementing the same interface as the bean they decorate
How CDI Enhances Application Development
Loose Coupling
Extensibility
Integration
Productivity
Loose Coupling
By managing dependencies externally, CDI reduces the coupling between components, making the system more modular and easier to maintain and test
Extensibility
CDI's dynamic nature allows developers to extend or modify the application behavior without changing the existing codebase, simply by adding or modifying beans, interceptors, and decorators
Integration
CDI integrates seamlessly with other Jakarta EE specifications, such as Jakarta Persistence, Jakarta Transactions, and Jakarta Security, providing a uniform and integrated development experience
Productivity
By automating many of the tedious and error-prone tasks, such as lifecycle management and dependency resolution, CDI allows developers to focus on writing business logic rather than boilerplate code
Creating and Injecting Beans in CDI
Beans are the building blocks of the application, Java objects managed by the CDI container, with their lifecycle, dependencies, and interactions controlled and facilitated by the container
Creating Beans
Beans are defined as classes annotated with a scope, indicating how the CDI container should manage their lifecycle
Injecting Beans
The process by which the CDI container provides an instance of a bean to another bean that requires it, typically done via field, method, or constructor injection using the @Inject annotation
Detailed Explanation of the Injection Process
Bean Discovery
Dependency Resolution
Context Management
Injection
Bean Discovery
CDI scans the classpath for classes annotated with bean-defining annotations and registers them as beans
Dependency Resolution
The container uses the type of the injection point to find a bean that satisfies the dependency
Context Management
The container manages the lifecycle of the bean instance based on the scope of the bean to be injected
Injection
The container injects the bean instance into the injection point, fulfilling the dependency
Interceptors are used to implement cross-cutting concerns, such as logging, security, auditing, or transaction management, in a centralized and reusable manner
Understanding CDI Interceptors
Interceptor Binding
Interceptor Class
Lifecycle Events
Interceptor Binding
A custom annotation that specifies when the interceptor should be applied
Interceptor Class
Contains the logic to be executed when the intercepted method is called
Lifecycle Events
Interceptors can act on different lifecycle events of a bean, such as method invocation, construction, or destruction
Interceptors
Can be applied to business methods to execute additional logic before or after the method execution
Understanding CDI Interceptors
1. Interceptor Binding: Define an interceptor binding annotation
2. Interceptor Class: Create the interceptor class
3. Lifecycle Events: Interceptors can act on different lifecycle events of a bean
Steps to Create CDI Interceptors
1. Define an Interceptor Binding Annotation
2. Implement the Interceptor Class
Interceptor Binding Annotation
Custom annotation used to link the interceptor with the target method(s) or class
Interceptor Binding Annotation
@InterceptorBinding marks it as an interceptor binding
@Target specifies where it can be applied
@Retention indicates it should be available at runtime
Interceptor Class
@Interceptor marks the class as an interceptor
@AroundInvoke defines the logic to be executed around the invocation of the method it intercepts