Three Types of Dependency Injection in Spring
Fast recall
Quick revision
Core answer
Whether you know all three DI styles and can justify why constructor injection is the production default, not just recite them.
Learners only know field injection because @Autowired on a field is the shortest to type, and can't explain the testability cost.
State clearly that constructor injection is recommended, then back it with final fields, plain-Java testing, and fail-fast startup.
Interview-ready guide
Interview answer
Spring supports three types of dependency injection.
The first is constructor injection, where you pass dependencies through the class constructor. That's the recommended approach because it lets you make fields final and guarantees every required dependency is provided up front. The second is setter injection, where you use a setter method to inject a dependency after the object is created.
That works well for optional dependencies that aren't critical to the class. The third is field injection, where you put the @Autowired annotation directly on a field. It's the shortest to write, but it's discouraged in production because you can't make the field final and it's harder to unit test.
Here's a concrete example. In an OrderService you'd use constructor injection for the PaymentGateway, because you can't process an order without it. You'd use setter injection for a NotificationService, because sending a confirmation is nice to have but not essential.
Field injection might show up in older code, but modern teams avoid it. The mistake Learners make is using field injection everywhere because it looks clean, and that creates real problems when you try to test the class without starting the whole Spring container. always say constructor injection is the industry default, then explain that it gives you immutability and easy testing.
Three Types of Dependency Injection in Spring
Direct Answer
The three DI types are constructor injection (dependencies via the constructor — the recommended default), setter injection (via setter methods — for optional dependencies), and field injection (@Autowired directly on a field — convenient but discouraged in production). Constructor injection wins because it allows final fields and makes the class testable without Spring.
Code Example
@Service
public class OrderService {
private final PaymentGateway paymentGateway; // constructor-injected (required)
private NotificationService notificationService; // setter-injected (optional)
@Autowired
private AuditLogger auditLogger; // field-injected (discouraged)
// Constructor injection - recommended for required dependencies.
// With a single constructor, Spring wires it without @Autowired (since 4.3).
public OrderService(PaymentGateway paymentGateway) {
this.paymentGateway = paymentGateway;
}
// Setter injection - for an optional dependency.
@Autowired(required = false)
public void setNotificationService(NotificationService notificationService) {
this.notificationService = notificationService;
}
public void processOrder(Order order) {
paymentGateway.charge(order.getAmount()); // required, always present
if (notificationService != null) { // guard the optional dependency
notificationService.sendConfirmation(order);
}
}
}
Common Mistakes & Pitfalls
- Using field injection everywhere: Learners see @Autowired on a field and assume it's the cleanest approach, but it makes unit testing harder because you can't pass mocks without Spring's test context.
- Not making constructor-injected fields final: With constructor injection, declare the field
finalto guarantee immutability and catch a missing dependency at compile time. - Mixing all three at random: Choosing injection types inconsistently across a codebase causes confusion. Pick a pattern — constructor for required, setter for optional — and stick to it.
Check your understanding
Answer these without looking back at the article.
- Why is constructor injection recommended over field injection?
- When would you use setter injection?
- What is the benefit of final fields in constructor injection?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.