DEV Community

Cover image for Dependency Injection in Spring Boot?
Arul .A
Arul .A

Posted on

Dependency Injection in Spring Boot?

Introduction

Spring Boot is one of the most popular frameworks for building Java applications. One of its most powerful features is Dependency Injection (DI), which helps developers create flexible, maintainable, and scalable applications.

Dependency Injection allows Spring Boot to manage the creation and injection of objects automatically, reducing manual coding and improving application design.

What is Dependency Injection?

Dependency Injection is a design pattern where an object's dependencies are provided by an external source rather than being created inside the object itself.

A dependency is simply an object that another object needs to perform its work.

Without Dependency Injection

public class UserService {

    private UserRepository userRepository = new UserRepository();

}
Enter fullscreen mode Exit fullscreen mode

In this example, UserService creates its own UserRepository object. This creates tight coupling between the two classes.

With Dependency Injection

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

}
Enter fullscreen mode Exit fullscreen mode

Here, Spring Boot automatically creates and injects the UserRepository object into UserService.

Why is Dependency Injection Important?

Dependency Injection provides several benefits:

  • Reduces tight coupling between classes
  • Improves code maintainability
  • Makes unit testing easier
  • Encourages reusable components
  • Simplifies object management

These advantages make applications more scalable and easier to maintain over time.

Understanding Spring Beans

A Spring Bean is an object managed by the Spring IoC (Inversion of Control) Container.

Spring automatically creates beans for classes annotated with:

  • @Component
  • @Service
  • @Repository
  • @Controller
  • @RestController

The Spring Container is responsible for creating, configuring, and managing these beans throughout the application's lifecycle.

Common Annotations Used in Dependency Injection

@Component

The @Component annotation tells Spring that a class should be managed as a bean.

@Component
public class EmailService {

    public void sendEmail() {
        System.out.println("Email Sent");
    }
}
Enter fullscreen mode Exit fullscreen mode

@Service

The @Service annotation is used for classes that contain business logic.

@Service
public class UserService {

    public String getUserDetails() {
        return "User Details";
    }
}
Enter fullscreen mode Exit fullscreen mode

@Repository

The @Repository annotation is used for database-related operations.

@Repository
public class UserRepository {

    public String findUser() {
        return "Arul";
    }
}
Enter fullscreen mode Exit fullscreen mode

@Autowired

The @Autowired annotation tells Spring to inject a required dependency automatically.

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public String getUser() {
        return userRepository.findUser();
    }
}
Enter fullscreen mode Exit fullscreen mode

Constructor Injection (Recommended)

Constructor Injection is considered the best practice in modern Spring Boot applications.

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public String getUser() {
        return userRepository.findUser();
    }
}
Enter fullscreen mode Exit fullscreen mode

Benefits of Constructor Injection

  • Better testability
  • Improved readability
  • Supports immutability
  • Clearly defines required dependencies

How Dependency Injection Works

The Spring Framework follows these steps:

  1. Spring Boot starts the application.
  2. Component scanning identifies annotated classes.
  3. Spring creates bean instances.
  4. Dependencies are detected.
  5. Required beans are injected automatically.
  6. The application becomes ready to handle requests.

This entire process is managed by the Spring IoC Container.

Real-World Example

Consider an Employee Management System.

Repository Layer

@Repository
public class EmployeeRepository {

    public String getEmployee() {
        return "Arul";
    }
}
Enter fullscreen mode Exit fullscreen mode

Service Layer

@Service
public class EmployeeService {

    private final EmployeeRepository employeeRepository;

    public EmployeeService(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }

    public String fetchEmployee() {
        return employeeRepository.getEmployee();
    }
}
Enter fullscreen mode Exit fullscreen mode

Controller Layer

@RestController
@RequestMapping("/employee")
public class EmployeeController {

    private final EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    @GetMapping
    public String getEmployee() {
        return employeeService.fetchEmployee();
    }
}
Enter fullscreen mode Exit fullscreen mode

Request Flow

Client Request → Controller → Service → Repository → Database

Spring automatically injects the required dependencies at each layer.

Top comments (0)