In this tutorial, we will learn the basic concept of Inversion of control and Dependency Injection.
The core of the spring framework is based on the IOC principle. IOC and DI are closely related concepts. They describe the different aspects of how the spring manages the objects and their interaction. Let's look into each concept.
Inversion of Control(IOC)
IOC is a design principle where the control of object creation, lifecycle and its management is transferred to a spring. Let's see the example of creating two services i.e DatabaseService and UserService
In non-IOC applications, the application code is responsible for creating and managing the DI
DatabaseService dbService = new DatabaseService();
UserService userService = new UserService(dbService);
Here, first, we create the database service object and inject it into user service as a DI resulting in a tight coupling
public class UserService {
private final DatabaseService dbService;
public UserService() {
this.dbService = new DatabaseService(); // Tight coupling
}
}
With IOC approach
@Component
public class UserService {
private final DatabaseService dbService;
@Autowired
public UserService(DatabaseService dbService) {
this.dbService = dbService;
}
}
Here, With IoC, the spring framework itself is responsible for creating and injecting dependencies. Here our application code is not responsible for creating both the object rather spring does. We only provide the metadata @Component and @Autowired to the spring container. UserService doesn't create the DatabaseService but Spring provides it with the help of annotation provided
Dependency Injection(DI)
DI is a design pattern that implements IoC by injecting an object's dependencies at runtime. That simply means it's a mechanism used to achieve IoC. It simply provide the instances of your application classes with all the dependencies they need.
Here are some advantages of using DI
- Loose coupling
DI allows components to be loosely coupled. This makes it easier to modify or replace dependencies without affecting other components.
- Simplify application configuration
DI uses configuration files, such as XML, annotations, or Java-based configuration, to define the dependencies, making it easier to switch configurations without changing the code.
- Improve code maintenance
DI reduces the amount of code to write to wire the components of the application together. As dependencies are managed externally via a Spring's IoC container; it centralizes configuration and makes the application more modular
- Testability
With DI, it's easier to write unit tests for components. Since dependencies can be injected as mock or stub objects.
- Easier Integration with Frameworks and Libraries
Spring's IoC container can manage their dependencies alongside with application's components, enabling cleaner integration and easier management of external resources.