What is dependency injection in Java?
Dependency injection (DI) is a design pattern implementing the Inversion of Control (IoC) principle. Instead of a class creating its own dependencies with new, those dependencies are provided (injected) from outside — by a framework, factory, or test harness. The class declares what it needs; something else decides what to provide.
There are three injection styles. Constructor injection passes dependencies through the constructor: the object is fully initialized on creation, all dependencies are visible, and the class can be declared immutable. This is the preferred style. Setter injection provides dependencies through setter methods after construction, useful for optional dependencies. Field injection injects directly into annotated fields — convenient but problematic for testing because the field is not accessible without a DI framework or reflection.
Spring Framework is the dominant DI container in the Java ecosystem. It manages bean lifecycle and wiring. With Spring, you annotate a class with @Component (or @Service, @Repository) and declare dependencies with @Autowired on constructors, setters, or fields. The Spring IoC container creates and wires beans at application startup. Java EE (now Jakarta EE) provides the CDI specification with @Inject for the same purpose.
The core benefit is testability. A class that creates its own dependencies is hard to unit test because you cannot substitute a mock. A class that accepts its dependencies via constructor can be instantiated in a test with mock objects, isolating behavior entirely. The second benefit is decoupling: your class depends on an interface, not a concrete implementation. The injected concrete type can be swapped without changing the class.
DI also centralizes configuration: which implementations to use, lifecycle scope (singleton, prototype, request-scoped), and initialization order are managed in one place rather than scattered across the codebase.
Explains that dependencies are provided externally rather than created internally, names the three injection styles, and gives testability as the key benefit.
Adds the IoC principle relationship, explains why constructor injection is preferred (immutability, visibility), names Spring/@Autowired or Jakarta CDI/@Inject, and explains the interface-based decoupling benefit.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment