DI and CDI
Tags: springboot, di, javacdi
Published: 2023-10-30 05:39:31

## DI (Dependency Injection)
Examples for field injection, constructor injection, and method injection using the Spring Framework for dependency injection:

**1. Field Injection:**

Field injection involves injecting dependencies directly into fields of a class using annotations like `@Autowired` or `@Resource`. Here's an example:

```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    public void doSomething() {
        // Use MyRepository to perform some operation
    }
}
```

In this example, `MyService` has a field `myRepository`, which is automatically injected using field injection.

**2. Constructor Injection:**

Constructor injection involves injecting dependencies through a class constructor. It's considered a best practice for dependency injection because it enforces the requirement of essential dependencies during object creation. Here's an example:

```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void doSomething() {
        // Use MyRepository to perform some operation
    }
}
```

In this example, `MyService` is constructed with a constructor that takes `MyRepository` as a parameter, and Spring automatically injects the dependency during object creation.

**3. Method Injection:**

Method injection involves injecting dependencies into specific methods of a class. This is less common than field or constructor injection and is often used when you need to provide a dependency to a specific method. Here's an example:

```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    private MyRepository myRepository;

    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void doSomething() {
        // Use MyRepository to perform some operation
    }
}
```

In this example, `MyService` provides a setter method (`setMyRepository`) to inject the `MyRepository` dependency. Spring uses this method to inject the dependency when needed.

While all three approaches can be used for dependency injection, constructor injection is generally recommended as it promotes clearer and more testable code by ensuring that dependencies are provided when an object is created. The choice of injection method depends on your specific requirements and design preferences.

Here are some considerations for each approach:

**Field Injection:**

- Pros:
 + Concise and requires less code. 
 + Suitable for cases where you have a single dependency.
- Cons:
 + Constructor is not explicitly defined, making it less obvious what dependencies are required.
 + Difficult to enforce that a required dependency is always  + provided because the field can be null.
 + Limited control over the initialization order of dependencies.

**Constructor Injection:**
- Pros:
 + Explicitly defines the required dependencies in the constructor, making it clear what the class depends on.
 + Provides better control over the order of initialization.
 + Helps ensure that all required dependencies are available when the object is created, preventing potential NullPointerExceptions.
- Cons:
 + Requires more code compared to field injection, especially if you have multiple dependencies.

## CDI (Contexts and Dependency Injection)
CDI (Contexts and Dependency Injection) is a specification in the Java EE (Enterprise Edition) platform that provides a powerful and flexible way to manage and inject dependencies in Java EE applications. Here's an example of CDI with explanations in the code:

**1. Create a CDI bean:**

First, create a CDI bean, which is a Java class that you want to manage and inject. In this example, we'll create a simple `GreetingService` bean.

```java
import javax.enterprise.context.RequestScoped;

@RequestScoped
public class GreetingService {

    public String getGreeting() {
        return "Hello, CDI!";
    }
}
```

- `@RequestScoped`: This annotation specifies that the bean's lifecycle is tied to the HTTP request. CDI offers various scopes, and `@RequestScoped` is just one of them.

**2. Inject the CDI bean:**

Next, create a class where you want to inject the CDI bean. In this case, we'll create a `GreetingController` to inject the `GreetingService`.

```java
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

@RequestScoped
public class GreetingController {

    @Inject
    private GreetingService greetingService;

    public String getGreetingMessage() {
        return greetingService.getGreeting();
    }
}
```

- `@Inject`: This annotation is used for field injection, indicating that you want to inject the `GreetingService` into the `GreetingController`.

**3. Use the CDI bean:**

Finally, you can use the `GreetingController` in your application.

```java
public class MainApplication {

    public static void main(String[] args) {
        GreetingController greetingController = new GreetingController();
        String greetingMessage = greetingController.getGreetingMessage();
        System.out.println(greetingMessage);
    }
}
```

In this code, we create a `GreetingController` instance and call the `getGreetingMessage` method, which, in turn, uses the injected `GreetingService` to retrieve a greeting message.

**Explanation:**

- CDI manages the lifecycle and dependencies of the `GreetingService` and `GreetingController` beans. In this example, both beans are annotated with `@RequestScoped`, which means a new instance of each bean is created for each HTTP request.

- `@Inject` is used for dependency injection. CDI handles the injection of the `GreetingService` into the `GreetingController` automatically.

- This is a simplified example. In a Java EE application, CDI can be used for managing more complex beans, providing different scopes (e.g., `@SessionScoped`, `@ApplicationScoped`), and enabling other features like events and interceptors.

CDI simplifies the management and injection of beans, making Java EE applications more modular and easier to maintain. It also promotes loose coupling and allows for better testing of components.