Prefer constructor injection over @Autowired fields
ID |
java.spring_prefer_constructor_injection |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Best Practice |
Language |
Java |
Tags |
best-practice, reliability, spring |
Description
Reports fields annotated with @Autowired. Field injection hides dependencies, prevents immutability, and makes unit testing harder. Constructor injection should be preferred.
Rationale
Field injection via @Autowired has several drawbacks:
-
Dependencies are hidden — the class’s API does not reveal what it needs.
-
Fields cannot be declared
final, so the object is mutable after construction. -
Unit testing requires reflection to set the private field, making tests fragile.
-
The class cannot be instantiated outside of a Spring container.
Since Spring 4.3, a single-constructor bean is auto-wired implicitly, so @Autowired is not even needed on the constructor.
// Bad - field injection
@Service
public class UserService {
@Autowired
private UserRepository repo;
}
Remediation
Replace field injection with constructor injection.
// Good - constructor injection, immutable
@Service
public class UserService {
private final UserRepository repo;
public UserService(UserRepository repo) {
this.repo = repo;
}
}