Field vs Constructor Injection Spring | Java Fresher Interview
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
I use constructor injection for required collaborators because the constructor states what the class needs and allows those fields to be final. For example, a test can create new OrderService(repository, gateway) with two Mockito mocks and no Spring context; the compiler also prevents construction when one required argument is missing. Field injection lets Spring set private fields after construction, but it hides required inputs from normal object creation and leaves the object temporarily incomplete. Spring can manage both styles, yet constructor injection exposes a circular dependency clearly during context creation. A setter can still make sense for a genuinely optional or replaceable collaborator with a valid default.
Field vs Constructor Injection Spring | Java Fresher Interview
Direct Answer
Constructor injection makes required dependencies explicit, supports final fields, and lets tests construct the class with normal Java. Field injection hides required inputs and needs the container or reflection-based test support. Spring can inject either style, but constructor injection gives an object that cannot be created without its required collaborators.
Code Example
// RECOMMENDED: Constructor injection with final fields
@Service
class OrderService {
private final PaymentGateway paymentGateway;
private final InventoryRepository inventoryRepo;
// Single constructor - Spring auto-wires without @Autowired since Spring 4.3
public OrderService(PaymentGateway paymentGateway, InventoryRepository inventoryRepo) {
this.paymentGateway = paymentGateway;
this.inventoryRepo = inventoryRepo;
}
public void processOrder(Order order) {
inventoryRepo.reserve(order.getItems());
paymentGateway.charge(order.getTotal());
}
}
// AVOID: Field injection with mutable state
@Service
class OrderServiceFieldInjection {
@Autowired private PaymentGateway paymentGateway; // hidden dependency
@Autowired private InventoryRepository inventoryRepo; // mutable
// Dependencies not visible in constructor - harder to test
public void processOrder(Order order) {
inventoryRepo.reserve(order.getItems());
paymentGateway.charge(order.getTotal());
}
}
Common Mistakes & Pitfalls
- Choosing Field Injection for Brevity: Freshers pick @Autowired field injection because it's fewer lines of code, not realizing they're sacrificing testability and immutability.
- Mixing Injection Types: Using constructor injection for some dependencies and field injection for others creates inconsistency and confusion about which are mandatory.
- Not Using Final Fields: Declaring constructor-injected dependencies without final allows accidental reassignment and signals to readers that the field might change, when it shouldn't.
- Ignoring Circular Dependencies: Field injection can mask circular dependency issues until runtime; constructor injection surfaces them immediately during Spring context startup.
Check your understanding
Answer these without looking back at the article.
- How does Lombok @RequiredArgsConstructor work?
- What is circular dependency and how does Spring handle it?
- How does Spring Boot auto-configure constructor injection?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.