Dependency Injection
Dependency Injection (DI) is the technique of providing an object's dependencies from the outside rather than creating them internally.
Without DI (Tightly Coupled)
// BAD: Class creates its own dependencies
public class OrderService {
private final OrderRepository orderRepository = new OrderRepository(); // Hard-coded!
private final PaymentService paymentService = new PaymentService(); // Hard-coded!
private final EmailService emailService = new EmailService(); // Hard-coded!
// Impossible to test — can't mock dependencies
}
With DI (Loosely Coupled)
// GOOD: Dependencies injected from outside
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentService paymentService;
private final EmailService emailService;
// Spring creates and injects these automatically
public OrderService(OrderRepository orderRepository,
PaymentService paymentService,
EmailService emailService) {
this.orderRepository = orderRepository;
this.paymentService = paymentService;
this.emailService = emailService;
}
}
Three Types of Injection
1. Constructor Injection (Recommended)
@Service
public class ProductService {
private final ProductRepository repository;
@Autowired // Optional in Spring 4.3+
public ProductService(ProductRepository repository) {
this.repository = repository;
}
}
2. Setter Injection
@Service
public class ProductService {
private ProductRepository repository;
@Autowired
public void setRepository(ProductRepository repository) {
this.repository = repository;
}
}
3. Field Injection (Not Recommended)
@Service
public class ProductService {
@Autowired // Makes testing difficult
private ProductRepository repository;
}
Best Practices
Key Principles
- Follow SOLID principles
- Write clean, readable code
- Test thoroughly
- Document decisions
- Monitor in production
Implementation
- Start simple, refactor as needed
- Use established patterns
- Consider trade-offs
- Review with peers
Continuous Improvement
- Learn from incidents
- Update documentation
- Share knowledge
- Mentor others
Key Points
- Understanding Dependency Injection is essential for production systems
- Always consider scalability and maintainability
- Test thoroughly before deploying to production
- Monitor performance and set up alerting
Common Patterns
- Validation: Always validate input at the boundary
- Error Handling: Use structured error responses
- Logging: Log key events for debugging
- Testing: Unit, integration, and load tests
- Documentation: Keep docs updated with code changes
Practice Problems
Design and implement a solution for Dependency Injection in a backend system. Consider scalability, error handling, and production readiness.
Solution
// Dependency Injection implementation
// Key aspects: validation, error handling, logging, testing
public class DependencyInjection {
// Production-ready implementation
}Identify and handle edge cases for Dependency Injection. What happens under high load, with invalid input, or during failures?
Solution
// Edge case handling:
// 1. Null/empty input -> validation
// 2. High load -> rate limiting, queuing
// 3. Failures -> retries, circuit breaker
// 4. Concurrent access -> locks, idempotencyWrite a testing strategy for Dependency Injection. Include unit tests, integration tests, and performance tests.
Solution
// Test plan:
// - Unit: 80% coverage target
// - Integration: API contracts
// - Performance: latency, throughput
// - Chaos: failure injectionQuiz
1. Why is constructor injection preferred over field injection?
2. What is the purpose of @Qualifier in Spring?
3. What is the primary purpose of Dependency Injection?
4. What is a common mistake when implementing Dependency Injection?
Flashcards
Question
What is Dependency Injection?
Click to reveal answer
Answer
Providing an object's dependencies from outside rather than creating them internally
Question
Why use constructor injection?
Click to reveal answer
Answer
Supports immutability, testing, null safety, and explicit dependencies
Question
What is Dependency Injection?
Click to reveal answer
Answer
Dependency Injection is a key concept in backend development.
Question
When to use Dependency Injection?
Click to reveal answer
Answer
Use Dependency Injection when building production systems that require reliability, scalability, and maintainability.
Question
Dependency Injection best practices
Click to reveal answer
Answer
Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.
Revision Notes
Key Takeaways
- 1.Dependency Injection provides objects with their dependencies from outside rather than creating them internally
- 2.Constructor injection is recommended because it supports immutability, testability, and null safety
- 3.Field injection makes testing difficult because dependencies cannot be mocked easily
- 4.Spring automatically manages bean creation and dependency wiring
- 5.Use @Qualifier when multiple beans of the same type exist, @Primary to mark a default
Interview Tips
- •Explain why constructor injection is preferred over field injection (immutability, testing, explicit dependencies)
- •Discuss the benefits of loose coupling for testability and maintainability
- •Know when to use @Qualifier vs @Primary for resolving multiple bean implementations
Cheat Sheet
Dependency Injection
- DI: provide dependencies from outside, don't create internally
- Constructor injection: recommended, supports final fields
- Setter injection: optional dependencies
- Field injection: not recommended, hard to test
- Spring auto-wires beans via @Autowired (optional in Spring 4.3+)
- @Qualifier: select specific bean when multiple exist
- @Primary: mark default bean implementation