Inversion of Control (IoC) and Dependency Injection (DI) are related concepts, but they are not the same thing.
Question. Is Dependency Injection the same as Inversion of Control?
Answer: No. IoC is a principle, while DI is one way to implement that principle.
1. What is Inversion of Control (IoC)?
Normally, an object creates and manages its own dependencies.
Without IoC
public class OrderService {
private PaymentService paymentService;
public OrderService() {
paymentService = new PaymentService();
}
public void placeOrder() {
paymentService.processPayment();
}
}
What happens here?
paymentService = new PaymentService();
OrderService is responsible for:
- Creating the dependency
- Managing the dependency
- Using the dependency
The control is inside OrderService
Problem
Suppose tomorrow you want:
CreditCardPaymentService instead of PaymentService
You must modify: OrderService
This creates tight coupling.
IoC Concept
With IoC: Object creation responsibility is moved outside the class.
Instead of: OrderService creates PaymentService
we do:
- Someone else creates PaymentService
- Someone else gives it to OrderService
Control is inverted.
That's why it is called: Inversion of Control
Real-Life Example
Imagine a restaurant.
Without IoC - You go into the kitchen and cook your own food.
Customer --> Kitchen --> Cooks food
Customer controls everything.
With IoC - You sit at the table.
Waiter brings food.
Customer <-- Waiter <-- Kitchen
Customer doesn't control food preparation.
Control has been inverted.
2. What is Dependency Injection (DI)?
Dependency Injection is a technique used to achieve IoC.
Instead of creating dependencies yourself:
new PaymentService()
someone injects them.
Example
public class OrderService {
private PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void placeOrder() {
paymentService.processPayment();
}
}
Now:
OrderService orderService =
new OrderService(new PaymentService());
Dependency is injected from outside.
This is Dependency Injection.
IoC vs DI
Spring Boot Example
Let's see what Spring does internally.
Step 1: Component
@Service
public class PaymentService {
public void processPayment() {
System.out.println("Payment Processed");
}
}
Step 2: Dependent Class
@Service
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void placeOrder() {
paymentService.processPayment();
}
}
Notice: new PaymentService()
does not exist.
Step 3: Spring Starts
When application starts:
@SpringBootApplication
public class Application {
}
Spring scans:
@Service
@Component
@Repository
@Controller
classes. Spring finds:
PaymentService
OrderService
Step 4: Spring Creates Beans
Internally:
PaymentService paymentService =
new PaymentService();
Bean created.
Stored in IoC Container.
Spring Container
|
+--> PaymentService Bean
Step 5: Spring Finds Dependency
Spring sees:
public OrderService(PaymentService paymentService)
It understands: OrderService needs PaymentService
Step 6: Spring Injects Dependency
Internally:
OrderService orderService =
new OrderService(paymentService);
Spring passes the object.
This is Dependency Injection.
Internal Flow Diagram
Application Starts
|
V
Component Scan
|
V
Find PaymentService
|
V
Create PaymentService Bean
|
V
Find OrderService
|
V
OrderService requires PaymentService
|
V
Inject PaymentService Bean
|
V
Create OrderService Bean
|
V
Store in IoC Container
What is the IoC Container?
Spring's IoC Container is essentially a registry that manages objects (beans).
Simplified view:
ApplicationContext
|
+--> PaymentService
|
+--> OrderService
|
+--> UserService
The container:
- Creates objects
- Injects dependencies
- Manages lifecycle
- Destroys objects Types of Dependency Injection
1. Constructor Injection (Recommended)
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
Advantages:
- Immutable dependencies
- Easy testing
- Spring recommendation
2. Setter Injection
@Service
public class OrderService {
private PaymentService paymentService;
@Autowired
public void setPaymentService(
PaymentService paymentService) {
this.paymentService = paymentService;
}
}
3. Field Injection
@Autowired
private PaymentService paymentService;
Works, but generally discouraged because it makes testing harder.
Inversion of Control (IoC) is a design principle where the control of creating and managing objects is transferred from application code to a container or framework.
Dependency Injection (DI) is a technique used to implement IoC by supplying dependencies from outside rather than creating them inside the class.
Example:
Without DI:
PaymentService paymentService = new PaymentService();
With DI:
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
In Spring Boot, the IoC container (ApplicationContext) creates beans and injects dependencies automatically using constructor injection, thereby implementing IoC through Dependency Injection.

Top comments (0)