DEV Community

tonybui1812
tonybui1812

Posted on

DI and CDI

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:

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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:

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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:

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

import javax.enterprise.context.RequestScoped;

@RequestScoped
public class GreetingService {

    public String getGreeting() {
        return "Hello, CDI!";
    }
}
Enter fullscreen mode Exit fullscreen mode
  • @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.

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

@RequestScoped
public class GreetingController {

    @Inject
    private GreetingService greetingService;

    public String getGreetingMessage() {
        return greetingService.getGreeting();
    }
}
Enter fullscreen mode Exit fullscreen mode
  • @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.

public class MainApplication {

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

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.

Top comments (0)