Implementing Dependency Injection
1. Implementing Constructor Injection
| Benefit | Detail |
| Required deps | Cannot construct without |
| Immutable | final fields |
| Testable | Pass mocks directly |
| Spring | No annotation needed if single ctor |
Example: Constructor injection
@Service
public class OrderService {
private final OrderRepository repo;
private final PaymentGateway gateway;
public OrderService(OrderRepository repo, PaymentGateway gateway) {
this.repo = repo;
this.gateway = gateway;
}
}
2. Implementing Setter Injection
| Use Case | Detail |
| Optional deps | May be null |
| Reconfigurable | Change at runtime |
| Drawback | Mutable; risk of half-built object |
3. Understanding Field Injection
| Aspect | Detail |
| Syntax | @Autowired private Foo foo; |
| Pros | Concise |
| Cons | Hidden deps, hard to test, mutable DISCOURAGED |
4. Implementing Component Scanning
| Annotation | Role |
@Component | Generic |
@Service | Service layer |
@Repository | Persistence; exception translation |
@Controller | Web MVC |
@RestController | REST endpoints |
@Configuration | Bean definitions |
5. Implementing Bean Lifecycle
instantiate → populate → BeanNameAware/AppContextAware
→ @PostConstruct / InitializingBean.afterPropertiesSet
→ init-method → ready
→ @PreDestroy / DisposableBean.destroy → destroy-method
6. Implementing Scope Management
| Scope | Lifetime |
singleton | Per container (default) |
prototype | New per injection |
request | Per HTTP request |
session | Per HTTP session |
application | Per ServletContext |
websocket | Per WebSocket session |
7. Implementing Qualifier Annotations
Example: Disambiguate beans
@Qualifier("primaryDb")
@Service
public class PrimaryDbReader { ... }
@Service
public class ReportService {
public ReportService(@Qualifier("primaryDb") DbReader reader) { ... }
}
8. Implementing Conditional Beans
| Annotation | Condition |
@ConditionalOnProperty | Property exists/equals |
@ConditionalOnMissingBean | No matching bean |
@Profile("prod") | Active profile |
@ConditionalOnClass | Class on classpath |
9. Resolving Circular Dependencies
| Strategy | Detail |
| Refactor | Extract third bean |
| Setter inject | Break cycle (Spring) |
@Lazy | Proxy delays resolution |
| ApplicationEvent | Decouple via event |
Warning: Constructor injection cycles fail at startup — usually a design smell.
10. Implementing Primary Beans
Example: Default among multiple
@Primary
@Service
public class DefaultPaymentGateway implements PaymentGateway { ... }
@Service
public class StripeGateway implements PaymentGateway { ... }
// Injection of PaymentGateway picks DefaultPaymentGateway unless @Qualifier used.
11. Implementing Custom Scopes
| Step | Detail |
Implement Scope | Override get, remove |
| Register | CustomScopeConfigurer bean |
| Use | @Scope("tenant") |
12. Understanding Dependency Injection Containers
| Container | Style | Startup |
| Spring | Reflection | Slower; flexible |
| Dagger 2 | Compile-time | Fast; verbose |
| Micronaut | Compile-time AOT | Very fast |
| Quarkus | Compile-time + native | Native image friendly |
| Guice | Reflection | Lightweight |