Dependency Injection (DI) is the process where the Spring Container creates objects (beans) and injects their dependencies automatically instead of the class creating them itself.
OrderService ---> PaymentService
OrderService depends on PaymentService.
Spring will: 1. Create PaymentService 2. Create OrderService 3. Inject PaymentService into OrderService
Application Start
│
▼
Spring Boot ApplicationContext Created
│
▼
Component Scan
│
▼
Bean Definitions Registered
│
▼
Spring Container Creates Beans
│
▼
Dependencies Identified
│
▼
Dependencies Injected
│
▼
Bean Ready to Use
@Service
public class OrderService {
@Autowired
private PaymentService paymentService;
}
Step 1: Spring creates PaymentService Step 2: Spring creates OrderService Step 3: Spring uses reflection to set field
OrderService orderService = new OrderService(); Reflection ↓ orderService.paymentService = paymentService
✔ Simple ✔ Less code
❌ Hard to test ❌ Hidden dependency ❌ Breaks immutability ❌ Uses reflection
@Service
public class OrderService {
private PaymentService paymentService;
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
Step 1: Spring creates PaymentService Step 2: Spring creates OrderService Step 3: Spring calls setter method
OrderService orderService = new OrderService(); orderService.setPaymentService(paymentService);
✔ Optional dependencies ✔ Can modify dependency later ✔ Allows validation logic
❌ Dependency may remain null ❌ Object can be in invalid state
@Service
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
Step 1: Spring creates PaymentService Step 2: Spring calls constructor
OrderService orderService =
new OrderService(paymentService);
✔ Immutable ✔ Clear dependencies ✔ Best for unit testing ✔ Recommended by Spring
| Feature | Field Injection | Setter Injection | Constructor Injection |
|---|---|---|---|
| Dependency visibility | Hidden | Visible | Very clear |
| Immutability | No | No | Yes |
| Testing | Hard | Medium | Easy |
| Optional dependency | No | Yes | Possible |
| Spring recommendation | Avoid | Sometimes | Best |
@Autowired private PaymentService paymentService;
Spring injects dependency directly into the field using reflection. No method is involved.
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
Spring injects dependency by calling a setter method. You can add validation or logic inside the method.
| Feature | Field Injection | Setter Injection |
|---|---|---|
| Injection Method | Reflection | Method Call |
| Encapsulation | Breaks encapsulation | Preserves encapsulation |
| Testing | Hard | Easier |
| Custom Logic | Not possible | Possible |
Constructor Injection + final fields + Lombok @RequiredArgsConstructor
@Service
@RequiredArgsConstructor
public class OrderService {
private final PaymentService paymentService;
}
Field Injection → Avoid Setter Injection → Optional dependencies Constructor → Recommended