Field injection automatically fills class fields with needed parts. But it hides how things connect, making code harder to understand and test.
Field injection and why to avoid it in Spring Boot
@Autowired private SomeService someService;
public class MyClass {
@Autowired
private UserService userService;
}public class MyClass {
@Autowired
private EmailSender emailSender;
public void send() {
emailSender.sendEmail();
}
}This Spring Boot example shows field injection where NotificationService has a private field messageSender filled by Spring. When notifyUser() runs, it uses messageSender to print a message.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class NotificationService { @Autowired private MessageSender messageSender; public void notifyUser() { messageSender.send("Hello user!"); } } @Component class MessageSender { public void send(String message) { System.out.println("Sending message: " + message); } }
Field injection hides dependencies, making it hard to see what a class needs.
It makes unit testing difficult because you cannot easily provide mock dependencies.
Constructor injection is preferred because it clearly shows dependencies and supports testing better.
Field injection uses @Autowired on fields to inject dependencies automatically.
It is easy but hides how classes connect and makes testing harder.
Constructor injection is a better practice for clear, testable code.
Practice
@Autowired directly on fields in Spring Boot?Solution
Step 1: Understand field injection behavior
Field injection uses@Autowiredon fields, which hides the dependencies inside the class without showing them in the constructor.Step 2: Analyze impact on testing
Because dependencies are hidden, it becomes harder to create test instances with mocks or stubs, reducing testability.Final Answer:
It hides dependencies and makes testing harder -> Option DQuick Check:
Hidden dependencies = avoid field injection [OK]
- Thinking field injection causes syntax errors
- Believing field injection disables auto-configuration
- Assuming field injection requires manual object creation
Solution
Step 1: Identify constructor injection syntax
Constructor injection requires a constructor that accepts the dependency as a parameter and assigns it to a field.Step 2: Match the correct code
public MyClass(Service service) { this.service = service; } shows a constructor receivingServiceand assigning it, which is the correct pattern.Final Answer:
public MyClass(Service service) { this.service = service; } -> Option CQuick Check:
Constructor injection = constructor with parameters [OK]
- Confusing field injection with constructor injection
- Using manual object creation instead of injection
- Using setter injection when constructor injection is asked
public class MyService {
@Autowired
private Repository repo;
public String getData() {
return repo.fetch();
}
}What is a likely problem when writing unit tests for
MyService?Solution
Step 1: Understand field injection impact on testing
Field injection hides the dependency inside the private field, making it hard to inject a mock instance during unit tests.Step 2: Analyze testability of
SinceMyServicerepois private and injected by Spring, test code cannot easily replace it with a mock, limiting test control.Final Answer:
You cannot replacerepowith a mock easily -> Option BQuick Check:
Field injection blocks mock replacement [OK]
- Assuming compilation errors occur
- Thinking Spring throws exceptions on field injection
- Believing the field is always null at runtime
public class UserService {
@Autowired
private UserRepository userRepository;
public UserService() {}
public User findUser(Long id) {
return userRepository.findById(id).orElse(null);
}
}Solution
Step 1: Review injection style
The class uses field injection with@Autowiredon a private field, which hides dependencies.Step 2: Understand testing impact
Because dependencies are hidden, it is harder to inject mocks or stubs for unit testing, reducing testability.Final Answer:
Field injection hides dependencies making testing harder -> Option AQuick Check:
Field injection = hidden dependencies = testing difficulty [OK]
- Thinking constructor needs @Autowired always
- Believing fields must be static for injection
- Assuming methods must be static for injection
public class OrderService {
@Autowired
private PaymentService paymentService;
public boolean processOrder(Order order) {
return paymentService.charge(order.getAmount());
}
}How would switching to constructor injection improve this class?
Solution
Step 1: Understand constructor injection benefits
Constructor injection requires dependencies to be passed in explicitly, making them visible and clear in the class design.Step 2: Analyze testability improvements
Explicit dependencies allow easy replacement with mocks or stubs during testing, improving testability and code clarity.Final Answer:
It makes dependencies explicit and improves testability -> Option AQuick Check:
Constructor injection = explicit dependencies + better tests [OK]
- Thinking constructor injection removes @Autowired completely
- Believing constructor injection creates new instances automatically
- Assuming Spring injects without constructor or annotations
Ready to prove it?
Pass the test and this pattern moves unknown
