Dependency Injection (DI) is a design pattern where objects are provided with their dependencies instead of creating them directly.
It’s like saying:
“Hey, I don’t want to build this thing myself—just give me a ready-made one that I can use.”

🧠 Why Is It Important?
Without DI:
public class PaymentService {
private UserRepository repo = new UserRepository(); // tightly coupled
}
With DI:
public class PaymentService {
private final UserRepository repo;
public PaymentService(UserRepository repo) {
this.repo = repo; // loosely coupled, easier to test and replace
}
}
✅ Benefits of DI:
- Cleaner code
- Better testability (you can mock dependencies)
- Encourages separation of concerns
- Makes code easier to manage and scale
🌱 How Dependency Injection in Spring Boot works
Spring Boot automatically injects beans using:
@Autowired- Constructor injection
- Field injection
- Setter injection (less common)
Spring does this by:
- Scanning your classes for annotations like
@Component,@Service,@Repository, etc. - Creating instances of these classes (called beans)
- Injecting them into other beans where required
🛠️ 1. Using @Component to Define a Bean
Let’s say you have a simple service class:
@Component
public class EmailService {
public void sendEmail(String message) {
System.out.println("Sending email: " + message);
}
}
Now Spring knows to manage EmailService as a bean.
🔁 2. Injecting a Dependency Using @Autowired
@Service
public class NotificationService {
@Autowired
private EmailService emailService;
public void notifyUser() {
emailService.sendEmail("Welcome to Spring Boot!");
}
}
Here, Spring automatically injects an instance of EmailService into NotificationService.
💡 Best Practice: Constructor Injection
Instead of using @Autowired on fields, use constructor injection:
@Service
public class NotificationService {
private final EmailService emailService;
public NotificationService(EmailService emailService) {
this.emailService = emailService;
}
public void notifyUser() {
emailService.sendEmail("Welcome to Spring Boot!");
}
}
✅ Advantages:
- Easier to test
- Makes immutability possible
- Encouraged by modern Spring practices
📘 Note: Since Spring 4.3+, if a class has only one constructor, Spring automatically injects dependencies — no need for @Autowired.
💾 Example: Full Working Application
@SpringBootApplication
public class DiDemoApplication {
public static void main(String[] args) {
SpringApplication.run(DiDemoApplication.class, args);
}
}
EmailService.java
@Component
public class EmailService {
public void sendEmail(String message) {
System.out.println("Email Sent: " + message);
}
}
NotificationService.java
@Service
public class NotificationService {
private final EmailService emailService;
public NotificationService(EmailService emailService) {
this.emailService = emailService;
}
public void notify() {
emailService.sendEmail("Dependency Injection rocks!");
}
}
MyController.java
@RestController
public class MyController {
private final NotificationService notificationService;
public MyController(NotificationService notificationService) {
this.notificationService = notificationService;
}
@GetMapping("/send")
public String sendNotification() {
notificationService.notify();
return "Notification Sent!";
}
}
Visit: http://localhost:8080/send
✅ You should see:
Email Sent: Dependency Injection rocks!
🔐 What Happens Behind the Scenes?
- Spring Boot starts and scans your classes (
@ComponentScan) - It detects all
@Component,@Service,@Repository, etc. - It creates and manages their instances (beans)
- It injects dependencies where required using reflection
🚫 Common Mistakes to Avoid
| Mistake | Issue |
|---|---|
| Forgetting to annotate a class | Spring won’t recognize it as a bean |
Using field injection without @Autowired | Dependency will be null |
| Trying to inject a bean that’s not scanned | Injection fails with NoSuchBeanDefinitionException |
| Circular dependencies | Can lead to startup errors |
📘 FAQ
❓ Do I always need @Autowired?
Not if you’re using constructor injection and the class has only one constructor. Spring will inject automatically.
❓ Can I inject one service into multiple components?
Yes! Spring manages beans as singletons by default (unless specified otherwise), so you can reuse them.
❓ What if I have multiple implementations of a dependency?
Use @Qualifier to specify which one to inject.
@Autowired
@Qualifier("smsService")
private NotificationService service;
📚 External References
✅ Summary
| Concept | Description |
|---|---|
| DI (Dependency Injection) | Providing dependencies from outside |
@Component | Marks a class as a Spring bean |
@Autowired | Injects a dependency |
| Constructor Injection | Recommended, testable, and cleaner |
| Spring Container | Manages beans and performs the injection |
Spring Boot makes dependency injection effortless, letting you focus on your logic while it wires up everything behind the scenes.