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;
  }
}