Dependency Injection: Constructor and Setter

Harry · 11 Sep 2026 · 12 views

Dependency Injection: Constructor and Setter

Dependency injection (DI) means an object receives the things it needs from outside instead of creating them itself. Spring supports two main styles: constructor injection, where dependencies arrive as constructor arguments, and setter injection, where a setter assigns them after construction.

Constructor injection

Constructor injection makes dependencies mandatory and obvious. The class has no half-constructed state, and any missing dependency fails at startup. Modern Spring guidelines strongly recommend it, and with a single constructor Spring can even skip the @Autowired annotation entirely.

@Service
public class OrderService {
    private final OrderRepository repository;
    private final DiscountCalculator calculator;

    public OrderService(OrderRepository repository,
                        DiscountCalculator calculator) {
        this.repository = repository;
        this.calculator = calculator;
    }
}

Setter injection

Setter injection assigns dependencies after the object is created, making them optional or re-assignable. Use it for truly optional dependencies or when you need to change a dependency after construction, such as in some legacy or proxy scenarios. It exposes mutable state, so keep it for cases where that is the point.

Why it matters

DI decouples classes from how their dependencies are built. A service tested with a fake repository uses exactly the same class as production with a real one. This is what makes Spring applications easy to unit test.

Interfaces hide implementations

Inject interfaces rather than concrete classes whenever multiple implementations may exist. Then swapping behavior - say a real payment gateway for a sandbox - becomes a configuration change, not a code change.

Key Points

  • DI supplies dependencies from outside, reducing coupling and enabling tests.
  • Prefer constructor injection for mandatory dependencies.
  • Use setter injection for optional or reassignable dependencies.
  • Inject interfaces when several implementations could be used.
  • Missing constructor dependencies fail fast at startup.
Share this post:

Comments (0)

Please login or register to comment.