What is the difference between @Autowired field, constructor, and setter injection?
Compare Spring @Autowired field, constructor, and setter injection — see why constructor injection is preferred, with examples and interview answers.
Expected Interview Answer
They are three ways Spring injects dependencies: constructor injection passes them as constructor arguments, setter injection uses setter methods, and field injection sets them directly on fields via reflection. Constructor injection is the recommended approach because it supports final fields, guarantees required dependencies, and makes classes easy to test.
Constructor injection creates a fully initialized, immutable object and fails fast if a required dependency is missing, which also exposes design smells like too many dependencies. Setter injection is useful for optional or reconfigurable dependencies and allows resolving circular references. Field injection is the most concise but hides dependencies, prevents final fields, and makes unit testing without the Spring container harder because you cannot pass mocks through a constructor. Since Spring 4.3 a single constructor no longer needs an explicit @Autowired annotation.
- Constructor injection enforces required, immutable dependencies
- Constructor injection enables testing without the Spring container
- Setter injection cleanly handles optional dependencies
- Setter injection can break certain circular dependency deadlocks
- All three reduce boilerplate compared with manual wiring
AI Mentor Explanation
Constructor injection is like naming your full playing eleven before the toss — the team is complete and fixed the moment the match starts. Setter injection is like using a substitute fielder you can swap in later during play. Field injection is like a player mysteriously appearing on the pitch with no team-sheet entry — convenient, but nobody can see how they got selected.
Step-by-Step Explanation
Step 1
Identify the dependency
Determine whether a collaborator is required or optional for the class to function.
Step 2
Prefer the constructor
Declare required dependencies as final fields set through the constructor for immutability and fail-fast wiring.
Step 3
Use setters for optional
Expose a setter for dependencies that are optional or may be reconfigured after construction.
Step 4
Avoid field injection in code you test
Skip direct field injection so you can pass mocks via the constructor in plain unit tests.
Step 5
Let Spring auto-detect
With one constructor, omit @Autowired; Spring resolves and injects the arguments automatically since 4.3.
What Interviewer Expects
- Explaining all three injection styles clearly
- Stating constructor injection as the recommended default
- Knowing final fields require constructor injection
- Awareness that field injection hurts testability
- Understanding that single constructors need no @Autowired since 4.3
Common Mistakes
- Claiming field injection is best because it is shortest
- Not knowing final fields cannot be set by field or setter injection
- Forgetting constructor injection can expose too-many-dependency smells
- Assuming @Autowired is always required on constructors
- Ignoring that field injection makes container-free unit tests painful
Best Answer (HR Friendly)
“These are three ways Spring hands an object the other objects it needs — through the constructor, through setter methods, or straight onto its fields. The constructor way is preferred because the object is fully ready the moment it is built and it is the easiest to test.”
Code Example
@Service
public class OrderService {
private final PaymentGateway gateway;
private final InventoryRepository inventory;
// No @Autowired needed for a single constructor (Spring 4.3+)
public OrderService(PaymentGateway gateway, InventoryRepository inventory) {
this.gateway = gateway;
this.inventory = inventory;
}
}@Service
public class NotificationService {
private EmailSender emailSender; // optional dependency
@Autowired(required = false)
public void setEmailSender(EmailSender emailSender) {
this.emailSender = emailSender;
}
}
@Service
public class ReportService {
@Autowired // field injection: concise but hard to unit test
private MetricsClient metricsClient;
}Follow-up Questions
- Why is constructor injection preferred over field injection?
- How does field injection make unit testing harder?
- Which injection type can help resolve circular dependencies?
- When is @Autowired optional on a constructor?
- How do you inject an optional dependency safely?
MCQ Practice
1. Which injection type is generally recommended for required dependencies?
Constructor injection supports final fields, guarantees required dependencies, and keeps classes easy to test.
2. Why is field injection discouraged?
Field injection uses reflection, obscures a class's dependencies, prevents final fields, and complicates container-free unit tests.
3. When can you omit @Autowired on a constructor?
Since Spring 4.3, a class with a single constructor has its arguments autowired automatically without the annotation.
Flash Cards
Recommended injection type? — Constructor injection — immutable, required, testable.
Best for optional dependencies? — Setter injection.
Why avoid field injection? — Hides dependencies, blocks final fields, hard to unit test.
When is @Autowired optional on a constructor? — When there is exactly one constructor (Spring 4.3+).
Which injection helps circular deps? — Setter injection can break certain circular dependency deadlocks.
Continue Learning
Related Interview Questions
What are Spring bean scopes and how do singleton and prototype differ?
medium
What is the Spring bean lifecycle and what callbacks does it provide?
medium
What is @SpringBootApplication and what annotations does it combine?
easy
How does Spring Boot handle application configuration with application.properties and profiles?
medium