Spring Boot Best Practices

Chapter 2 · Practice 1 of 4

Use constructor injection with final fields

From Structure and dependency injection

Why it matters

Field injection with @Autowired on a private field looks short, but it hides dependencies, makes fields mutable and forces tests to use reflection or a Spring context to set them.

Constructor injection fixes all three:

  • Dependencies are visible in the constructor signature.
  • Fields can be final, so the object is fully built before use.
  • Unit tests call the constructor with fakes, with no Spring at all.

A class with a single constructor needs no @Autowired annotation. If a constructor grows past four or five parameters, that is a sign the class does too much, not a reason to switch back to field injection.

Example

Java
@Service
public class OrderService {
    private final OrderRepository orders;
    private final PaymentClient payments;

    public OrderService(OrderRepository orders, PaymentClient payments) {
        this.orders = orders;
        this.payments = payments;
    }
}