Short answer
Constructor injection is the default choice: it makes dependencies explicit, allows final fields for immutability and thread-safety, fails fast at startup on missing or circular dependencies, and lets you instantiate the class with plain new in tests without a Spring context.
Explanation
Setter injection is reserved for genuinely optional or reconfigurable dependencies. Field injection (@Autowired on a field) is discouraged in production because it hides dependencies, can't produce final fields, encourages too many collaborators, and forces reflection or a running context to test.
Common mistakes
- Using field injection in production code, which hides dependencies and blocks immutability.
- Not explaining that constructor injection works without Spring in tests.