Skip to content

Latest commit

 

History

History
134 lines (99 loc) · 6.3 KB

DI.md

File metadata and controls

134 lines (99 loc) · 6.3 KB

In Spring, Constructor Injection, Setter Injection, and Field Injection are three common methods for Dependency Injection (DI), each with its own way of providing dependencies to a class. Here's a breakdown of each method:


1. Constructor Injection:

In Constructor Injection, dependencies are provided through the constructor of the class. Spring automatically injects the required dependencies when the bean is created.

How it works:

  • The dependencies are passed as arguments to the class constructor.
  • This method makes the dependencies immutable, as they are provided when the object is created.
  • It is often considered the most recommended way because it ensures that all required dependencies are available at the time of object creation and makes the class easier to test.

Example:

@Component
public class UserService {

    private final UserRepository userRepository;

    @Autowired // Constructor injection
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void performAction() {
        userRepository.save();
    }
}

In this example:

  • UserService depends on UserRepository.
  • The dependency is injected via the constructor, and UserRepository is passed when the UserService object is created by the Spring container.
  • @Autowired is optional with Spring 4.3+, as Spring automatically detects a single constructor and uses it for injection.

Benefits of Constructor Injection:

  • Immutability: Once the object is created, its dependencies cannot be changed.
  • Mandatory Dependencies: All required dependencies must be provided, ensuring the class is in a valid state.
  • Easier to Test: Constructor-based injection is easier to mock or provide mock dependencies during testing.

2. Setter Injection:

In Setter Injection, dependencies are provided through setter methods after the object has been created.

How it works:

  • Spring calls the setter methods to inject the dependencies after the object is instantiated.
  • This method allows for optional dependencies because setter methods can be called or not.
  • It can also lead to mutable objects, as dependencies can be changed after object creation.

Example:

@Component
public class UserService {

    private UserRepository userRepository;

    @Autowired // Setter injection
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void performAction() {
        userRepository.save();
    }
}

In this example:

  • The UserRepository dependency is injected through the setUserRepository method.
  • @Autowired tells Spring to call this setter method to inject the dependency.

Benefits of Setter Injection:

  • Flexibility: Dependencies can be modified after object creation.
  • Optional Dependencies: Some dependencies can be optional, as Spring will only call the setter if the dependency is provided.
  • Easier to Implement: Useful in cases where the object’s dependencies are not known at the time of object creation.

3. Field Injection:

In Field Injection, dependencies are injected directly into the fields of the class.

How it works:

  • Spring injects the dependencies directly into the fields using reflection, without the need for setter or constructor methods.
  • This method is the most concise, but it is generally discouraged because it hides the dependencies of a class, making the code less explicit and harder to test.

Example:

@Component
public class UserService {

    @Autowired // Field injection
    private UserRepository userRepository;

    public void performAction() {
        userRepository.save();
    }
}

In this example:

  • UserRepository is injected directly into the userRepository field using @Autowired.
  • Spring automatically injects the dependency into the field when the UserService bean is created.

Benefits of Field Injection:

  • Conciseness: No need for constructor or setter methods, making the code shorter.
  • Simplicity: Easy to implement in small applications or prototypes.

Drawbacks of Field Injection:

  • Hidden Dependencies: The dependencies are not explicit, making it harder to understand the class’s dependencies.
  • Difficult to Test: Field injection is hard to mock or test directly, as the dependencies are injected via reflection.
  • Less Preferred: Many developers avoid field injection due to these drawbacks, especially in larger, more complex applications.

Summary of Differences:

Feature Constructor Injection Setter Injection Field Injection
Injection Location Constructor method Setter method Directly into fields
When Dependencies are Set At the time of object creation After the object is created Immediately when the class is instantiated
Immutability Dependencies are immutable Dependencies can be changed Dependencies can be changed
Mandatory Dependencies All dependencies must be provided Dependencies can be optional Dependencies can be optional
Ease of Testing Easier to test, as dependencies are explicit Easier to test with mock dependencies Harder to test due to hidden dependencies
Recommended Yes, generally preferred Useful for optional dependencies Generally not recommended in large applications

Best Practices:

  • Constructor Injection is generally preferred for mandatory dependencies and is more testable.
  • Setter Injection is useful when you have optional dependencies.
  • Field Injection should be avoided in favor of the other two methods for better clarity, maintainability, and testability.