Dependency Injection
Now that you know what the IoC container does, this page covers how you tell it what to inject. Spring supports three injection styles.
Constructor injection (recommended)
@Servicepublic class OrderService { private final PaymentGateway paymentGateway;
public OrderService(PaymentGateway paymentGateway) { this.paymentGateway = paymentGateway; }}Dependencies are declared once, in the constructor, and the field can be final. This makes the
class impossible to construct in an invalid state — a huge win for testability.
Setter injection
@Servicepublic class OrderService { private PaymentGateway paymentGateway;
@Autowired public void setPaymentGateway(PaymentGateway paymentGateway) { this.paymentGateway = paymentGateway; }}Useful for optional dependencies, but the object can briefly exist without them being set.
Field injection (avoid)
@Servicepublic class OrderService { @Autowired private PaymentGateway paymentGateway;}Concise, but it hides dependencies from the constructor signature, makes the class harder to unit
test without a DI framework, and prevents final fields. Prefer constructor injection by default.
Rule of thumb
- Required dependency → constructor injection.
- Optional dependency → setter injection.
- Field injection → only in quick prototypes or test classes.