Microservices · Lesson 5
Dependency Injection in Spring
What Dependency Injection Does
Dependency injection supplies an object with the collaborators it needs instead of making the object construct them internally. Spring manages these objects as beans and connects them through their constructors. This reduces coupling and makes unit tests straightforward.
Constructor Injection
Declare required dependencies in a constructor. The service then cannot be created in an incomplete state.
public interface CourseRepository {
String findTitle(String courseSlug);
}
public class CourseService {
private final CourseRepository repository;
public CourseService(CourseRepository repository) {
this.repository = repository;
}
public String titleFor(String courseSlug) {
return repository.findTitle(courseSlug);
}
}
In Spring, @Service marks the service and a repository bean satisfies its constructor. The framework manages the object graph while the class remains ordinary Java.
Injection Comparison
| Style | Strength | Concern |
|---|---|---|
| Constructor | Required dependencies are explicit | More constructor parameters |
| Setter | Optional configuration | Object can be incomplete |
| Field | Short syntax | Hidden dependencies and harder tests |
| Manual factory | Full control | More wiring code |
Common Mistake and Practices
Common Mistake: Injecting concrete infrastructure classes everywhere. Business code then depends on one implementation and becomes difficult to replace in tests or a later migration.
- Prefer constructor injection.
- Depend on interfaces at meaningful boundaries.
- Keep beans focused.
- Avoid service locator patterns.
- Detect circular dependencies early.
Real-World Use Case
A course service receives a repository and an event publisher through its constructor. Unit tests provide in-memory fakes, while production uses Spring-managed database and messaging implementations.
Quiz Check