Dependency Injection
Dependency Injection (DI) IoC ko IMPLEMENT karne ka main tareeka hai — ek object ki dependencies (jo objects usko chahiye) OUTSIDE se provide ki jaati hain, object khud unhe create nahi karta. Teen types: CONSTRUCTOR injection (dependencies constructor ke through, RECOMMENDED — immutable, mandatory dependencies clear hoti hain), SETTER injection (setter methods ke through, optional dependencies ke liye), FIELD injection (@Autowired directly field par, CONVENIENT but testing/immutability mein problematic).
Constructor injection BEST PRACTICE hai — dependency FINAL ho sakti hai (immutable), object CREATION ke waqt hi saari dependencies GUARANTEED milti hain (partial-initialized object impossible), aur unit testing mein MOCK dependencies pass karna easy hota hai (bina Spring container ke).
// Constructor injection — RECOMMENDED:
@Service
public class OrderService {
private final PaymentGateway gateway;
private final InventoryService inventory;
public OrderService(PaymentGateway gateway, InventoryService inventory) {
this.gateway = gateway;
this.inventory = inventory;
}
}
// Field injection — convenient, lekin AVOID karo:
@Service
public class OrderService {
@Autowired
private PaymentGateway gateway; // testing/immutability mein problematic
}- Constructor injection = RECOMMENDED (immutable, testable, mandatory)
- Setter injection = optional dependencies ke liye
- Field injection = convenient lekin AVOID karo (testing mushkil)
Constructor injection se dependencies FINAL declare ho sakti hain — ek baar set hone ke baad change NAHI ho sakti (immutability). Isse THREAD-SAFETY milती hai (koi accidental reassignment nahi), aur object hamesha COMPLETE state mein hota hai (kabhi "half-initialized" nahi milता).
@Service
public class OrderService {
private final PaymentGateway gateway; // final — immutable!
public OrderService(PaymentGateway gateway) {
this.gateway = gateway;
}
}Agar Bean A ko Bean B chahiye, aur Bean B ko Bean A chahiye (CONSTRUCTOR injection ke through), Spring EXCEPTION throw karта hai startup par — circular dependency resolve NAHI kar sakta constructor injection ke saath. Solution: design ko REFACTOR karo (ek third service nikaलो), ya setter/field injection use karo (jo lazy resolve ho sakti hai), ya @Lazy annotation.