Context and Dependency Injection beans
Contexts and Dependency Injection (CDI) is a framework that makes it easier to integrate Jakarta EE components of different types. CDI enables Java object dependencies to be automatically injected at run time, and helps manage the lifecycle of those dependencies.
CDI provides the following fundamental services:
Contexts, which help you bind the lifecycle and interactions of stateful components to well-defined, extensible contexts.
Dependency injection, which helps you inject components into an application in a type-safe way.
CDI is an essential element in MicroProfile, Java EE, and Jakarta EE. MicroProfile specifications take a CDI-first approach. They rely on the CDI extension mechanism, which implements more functions and enhances existing standards with new capabilities.
CDI beans
Beans are components that can be injected into each other with a dependency injection. Almost every Plain Old Java Object (POJO) with a constructor can be a bean. In CDI, a bean is a source of contextual objects that define application state and logic. The beans are managed by CDI containers by using bean-defining annotations. The container instantiates dependencies and controls when and how the components are instantiated and destroyed.
Annotations are metadata about code. You can use them to decorate a class, method, field, parameter, variable, constructor, or package. You can also use annotations to define the scope in which the bean is stored.
CDI scopes
Scopes define the state of a bean. The following CDI scope annotations control the lifecycle of the bean:
The
@ApplicationScoped
class-level annotation specifies that an instance is live when the application is active.The
@RequestScoped
class-level annotation specifies that a new instance of the bean is created for every request, such as a servlet request.The
@Dependent
class-level annotation specifies that the new instance belongs to another object. A dependent bean instance is never shared among different clients or different injection points. It is instantiated when the object it belongs to is created, and then destroyed when the object it belongs to is destroyed.
If no class-level annotation is defined, the @Dependent
annotation is the default.
Annotations that define CDI beans must be discovered. You can enable CDI annotation scanning by using a beans.xml
file in the META-INF folder of a .jar
file, or in the WEB-INF folder of a .war
file. This file can be empty, or it can contain code similar to the following example:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
// enable interceptors; decorators; alternatives
</beans>
The presence of an empty beans.xml
file or a beans.xml
file with the bean-discovery-mode="all"
attribute makes all of the potential objects CDI beans. Otherwise, only objects with CDI bean-defining annotations are CDI beans.
CDI bean injection
CDI injects defined beans into other components through the @Inject
annotation. For instance, the POJO in the following example is a CDI bean. Because the MyBean
class has the @ApplicationScoped
annotation, only one instance is created. You can use the same instance throughout the lifetime of the application:
@ApplicationScoped
public class MyBean {
int i=0;
public String sayHello() {
return "MyBean hello " + i++;
}
}
The MyRestEndPoint
class has the @RequestScoped
annotation in the following code, which means an instance is created for each request. CDI injects the same MyBean
instance into each request:
@RequestScoped
@Path("/hello")
public class MyRestEndPoint {
@Inject MyBean bean;
@GET
@Produces (MediaType.TEXT_PLAIN)
public String sayHello() {
return bean.sayHello();
}
}