What is Dependency Injection?
Dependency Injection is a design pattern used to implement Inversion of Control (IoC). Instead of a class creating its own dependencies, they are injected from outside. This makes code more flexible, testable, and maintainable.
- Dependency: An object that another object needs to function.
- Injection: The act of providing the dependency from outside the class.
Types of Dependency Injection in Java
- Constructor Injection: Dependencies are provided through the class constructor.
- Setter Injection: Dependencies are provided through setter methods.
- Interface Injection: Less common; dependencies are injected through an interface method.
Example: Constructor Injection
Let’s say we have a Service
that depends on a Repository
.
// Dependency
class Repository {
public void save(String data) {
System.out.println("Saving data: " + data);
}
}
// Dependent class
class Service {
private Repository repository;
// Constructor Injection
public Service(Repository repository) {
this.repository = repository;
}
public void process(String data) {
System.out.println("Processing data: " + data);
repository.save(data); // Using dependency
}
}
// Main class
public class Main {
public static void main(String[] args) {
// Creating the dependency
Repository repo = new Repository();
// Injecting the dependency into Service
Service service = new Service(repo);
service.process("Hello DI!");
}
}
Output:
Processing data: Hello DI!
Saving data: Hello DI!
Example: Setter Injection
class Service {
private Repository repository;
// Setter Injection
public void setRepository(Repository repository) {
this.repository = repository;
}
public void process(String data) {
System.out.println("Processing data: " + data);
repository.save(data);
}
}
public class Main {
public static void main(String[] args) {
Repository repo = new Repository();
Service service = new Service();
// Inject dependency via setter
service.setRepository(repo);
service.process("Hello Setter DI!");
}
}
Why Use DI?
- Reduces tight coupling between classes.
- Makes testing easier (can inject mock objects).
- Promotes code reuse and maintainability.
- Integrates well with frameworks like Spring, which manage dependencies automatically.