While @Autowired is Spring's field-injection annotation, constructor injection and setter injection are the two main alternatives for wiring dependencies, and constructor injection is generally the recommended default.
Key Points: • Constructor injection passes dependencies as constructor parameters, making them mandatory and enabling immutable, final fields. • Setter injection exposes setter methods for dependencies, suited to optional or reconfigurable collaborators. • Constructor injection makes classes easier to unit test because dependencies can be passed directly without a Spring context. • Since Spring 4.3, a single constructor doesn't even require an explicit @Autowired annotation. • Field injection via @Autowired is convenient but hides dependencies and complicates testing, so many teams avoid it.
Example: A UserService class that needs a UserRepository declares it as a final field set through the constructor, so Spring injects it automatically at bean creation and the dependency can never be left null.
Code Example:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}Interview Tip: A concise interview answer is:
"The main alternatives to field-based @Autowired are constructor injection and setter injection. I default to constructor injection because it makes dependencies explicit and immutable and it's easy to unit test without spinning up a Spring context, while setter injection is reserved for genuinely optional dependencies."