Introduction
Dependency Injection (DI) is a core concept in Spring Boot that promotes loose coupling and enhances code maintainability. It enables objects to receive their dependencies from an external source rather than creating them internally, making the application more modular and testable.
What is Dependency Injection?
Dependency Injection is a design pattern in which an object’s dependencies are provided externally, typically by a framework like Spring. Spring Boot uses the Spring IoC (Inversion of Control) container to manage dependencies.
Types of Dependency Injection in Spring Boot
- Constructor Injection
- Setter Injection
- Field Injection
Example: Implementing Dependency Injection in Spring Boot
Let’s create a simple Spring Boot application demonstrating dependency injection.
Step 1: Create a Service Interface
public interface GreetingService {
String greet(String name);
}
Step 2: Implement the Service
import org.springframework.stereotype.Service;
@Service
public class GreetingServiceImpl implements GreetingService {
@Override
public String greet(String name) {
return "Hello, " + name + "!";
}
}
Step 3: Inject the Service into a Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private final GreetingService greetingService;
@Autowired // Constructor Injection
public GreetingController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/greet")
public String greet(@RequestParam String name) {
return greetingService.greet(name);
}
}
Step 4: Run the Application
When you run the Spring Boot application and access http://localhost:8080/greet?name=John
, it will return:
Hello, John!
Types of Dependency Injection Explained
1. Constructor Injection (Recommended)
- Injects dependencies through a class constructor.
- Best suited for mandatory dependencies.
- Example:
@Autowired
public GreetingController(GreetingService greetingService) {
this.greetingService = greetingService;
}
2. Setter Injection
- Injects dependencies using setter methods.
- Suitable for optional dependencies.
- Example:
@Autowired
public void setGreetingService(GreetingService greetingService) {
this.greetingService = greetingService;
}
3. Field Injection (Not Recommended)
- Directly injects dependencies into fields using
@Autowired
. - Not recommended due to difficulty in unit testing.
- Example:
@Autowired
private GreetingService greetingService;
Conclusion
Spring Boot’s Dependency Injection feature helps in decoupling components, making applications modular and easy to test. Constructor injection is the most preferred approach, followed by setter injection. Field injection should be avoided for better testability and maintainability.