Constructor Injection vs. @Autowired: Spring Boot 3
Spring Boot 3, constructor injection is considered the best practice over @Autowired. Here's why:
1. Encourages Immutability
Constructor injection allows dependencies to be declared as final, ensuring they are initialized only once and cannot be reassigned.
@Component
public class MyService {
private final MyDependency myDependency;
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
2. Improves Testability
You can inject mock dependencies directly into the constructor for unit tests, eliminating the need to rely on Spring's DI framework.
MyService service = new MyService(mockDependency);
3. Avoids Reflection
@Autowired uses reflection, which can have minor performance impacts. Constructor injection resolves dependencies at compile-time, making it faster and cleaner.
4. Clear Dependency Visibility
All required dependencies are explicitly listed in the constructor, improving readability and maintainability.
public MyService(MyDependency1 dep1, MyDependency2 dep2) {
// Dependencies are obvious
}
5. Prevents Circular Dependencies
Constructor injection detects circular dependencies at compile-time, while field injection (@Autowired) may fail at runtime.
6. Compatibility with Non-Spring Frameworks
Constructor injection works seamlessly with frameworks that do not support annotations like @Autowired.
7. Encourages Dependency Injection Principles
Constructor injection explicitly enforces dependency injection principles, unlike @Autowired, which may obscure actual dependencies.
8. Alignment with Modern Spring Practices
Starting from Spring 4.3, Spring automatically resolves single-constructor classes without requiring @Autowired, making constructor injection concise.
@Component
public class MyService {
private final MyDependency myDependency;
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
When to Use @Autowired
There are still valid scenarios for @Autowired:
Conclusion
Constructor injection offers better immutability, testability, performance, and alignment with modern practices, making it the preferred choice in Spring Boot 3. Use @Autowired sparingly for legacy compatibility or specific use cases.
References