DI: dependency được cung cấp từ bên ngoài thay vì object tự new → giảm coupling, tăng testability (mock được khi test). Thay vì khởi tạo cứng new UserRepository() bên trong class, constructor nhận sẵn UserRepository từ ngoài — class chỉ khai báo cần gì, không quan tâm tạo thế nào.
3 cách inject:
- Constructor — KHUYẾN NGHỊ: immutable (final), required dependency rõ ràng, dễ test. Spring 4.3+ có 1 constructor thì khỏi @Autowired.
- Setter — cho dependency optional.
- Field (@Autowired trên field) — gọn nhưng anti-pattern: khó test, ẩn dependency.
IoC container (ApplicationContext) quản lý lifecycle bean + tự wiring qua component scan. (Code minh hoạ 3 kiểu: xem câu constructor/setter/field injection.)