1. Introduction
Java ee cdi mainly uses the @ Inject annotation to implement dependency injection, injecting managed beans into other resources managed by containers. In this tutorial, we will introduce several different optional policies in the CDI environment to implement dependency injection.
This tutorial is based on the following environment:
WeldIs the reference implementation of CDI.
2. constructor dependency Injection
- public class SomeBean {
-
- private final Service service;
-
- @Inject
- public SomeBean(Service service){
- this.service = service;
- }
-
- }
When the CDI container initializesSomeBeanWhen a bean instance of the type is created, it searches for the default constructor of the class without a parameter constructor) and uses it to create a bean instance. However, one exception is that when we use@ InjectIn this case, the container will use the constructor with annotation instead of the non-argument constructor, in addition, the dependent resources passed in through the constructor parameters are injected into the bean instance.
Note:: Remember that only one class can haveOne@ Inject annotation constructor.
In the preceding example, the container obtainsServiceAnd inject itSomeBeanIn the annotation constructor.
3. Field dependency Injection
- public class SomeBean {
-
- @Inject
- private Service service;
-
- }
In this case, when the container initializesSomeBeanType bean, it will put a correctServiceInstance injection to this field, even if this field isPrivateField, and no setter method is required.
4. initialize method dependency Injection
- public class SomeBean {
-
- private Service service;
-
- @Inject
- public void setService(Service service) {
- this.service = service;
- }
-
- }
In this case, when the container initializesSomeBeanType bean, it calls all@ InjectAnnotation method, and inject the dependency into the method through the method parameter.
@ Any Modifier
To provide fully loosely coupled applications, we usually inject interfaces into managed resources. What should we do when we have multiple beans that implement the given interface? We can also use@ AnyModifier and CDIInstanceInterface to inject all the bean implementations of this interface into a managed bean:
The @ Any qualifier
- public class SomeBean {
-
- @Inject
- public void listServiceImplementations(
- @Any Instance<Service> serviceList) {
-
- for(Service service : serviceList){
- System.out.println(service.getClass().getCanonicalName());
- }
-
- }
- }
@ AnyThe modifier tells the container that any available dependencies apply to the injection point, so the container injects them. If we have multiple implementations of interfaces and we only inject one of them-without any exclusion work-the container will complain and Cannot initialize the component successfully. We will introduce the dependency exclusion issue in other tutorials.
6. Inject to the producer Method
Parameters of the producer method can also be injected through the CDI container. See Java ee cdi Producer methods tutorial.
7. CDI proxy
If we do not involve the CDI proxy mechanism, this tutorial will be incomplete. When we inject a bean created in a different range from @ Dependent to another managed resource, the CDI container will not inject a direct reference of the injected bean.
For the bean scope in CDI, see Java ee cdi bean scopes.
Why does CDI use a proxy? If bean direct reference is injected, it will cause problems such as thread security or concurrent access to the managed bean.
Suppose a bean in the next Session range is injected into the bean in the Application range. Because the beans in the application scope are shared among all clients, if multiple clients access the beans in the application scope at the same time, there will be a high risk of this situation: A client accesses the bean in the session range being accessed by other clients.
To solve this problem, CDI creates a proxy and injects the proxy into the injection point. The proxy is responsible for processing the call to the injected bean and actually calling the correct bean instance.
The proxy created by CDI inherits the type of the injected bean. Imagine the following situation:
Bean in the Application and Session range
- @SessionScoped
- public class Service {
-
- public void doWork() {
- System.out.println("Working...");
- }
-
- }
-
-
- @ApplicationScoped
- public class SomeBean {
-
- @Inject
- private Service service;
-
- public void test(){
- service.doWork();
- }
-
- }
CDI injects the proxy of a session bean into an application bean. Every call to the session-range bean is performed through the proxy. The proxy redirects the call to the instance of the correct session-range bean, which belongs to the correct HTTP request session bean.
CDI creates a proxy by inheriting the class of the original bean and rewriting all non-private methods. A simple example of a typical proxy can be as follows:
CDI proxy example
- ublic class Service$Proxy$_$$_WeldClientProxy
- extends Service {
-
- @Override
- public void doWork() {
- Service instance = // ... resolve bean instance
- instance.doWork();
- }
-
- }
Because the CDI proxy is created by inheriting bean classes, when we discuss the scope of the non-dependent bean, you should understand that CDI has the following restrictions: