DEV Community

Alexander the dev
Alexander the dev

Posted on

Understanding Dependency Injection and Components in Java Spring Boot

Introduction

Welcome to the third part of our "Java Spring Boot for Beginners" series, dedicated to unraveling the essentials of dependency injection and components. My name is Alex, and today, we will delve deeper into how inversion of control (IoC) and components interplay within Spring Boot.

If you more of a visual person then you can watch the video in my channel https://youtu.be/j8XwEYJsejs

Welcome to Alexander The Dev: Understanding Dependency Injection and Components in Java Spring Boot


Understanding Dependency Injection

Dependency injection is a fundamental design pattern critical in software engineering, intended to implement inversion of control. It involves injecting class B directly into class A, eliminating the need for class A to create or manage class B on its own. This approach enhances the modularity of your application while making it easier to manage and test.

Spring Boot utilizes an IoC container to manage objects' lifecycle and configuration, which are known as beans. These beans form the backbone of any Spring application. The IoC container is responsible for injecting these into applications as needed, which allows for the efficient sharing of objects and resources.


Why Use Dependency Injection?

The primary advantage of using dependency injection is the decoupling of code. This decoupling significantly eases management, testing, and flexibility, as it allows the swapping of implementations without impacting dependent classes. Moreover, it simplifies testing endeavors by facilitating the mocking of dependencies during both unit and integration tests.


Illustrating Dependency Injection with Spring Boot

Diagram explains the dependency injection and the IoC container

To better explain dependency injection, let's examine a simple design scenario involving several classes: BookService, BookRepository, AuthorService, and AuthorRepository. Traditionally, class instances are created using the new keyword, but with Spring Boot, you can use annotations like @Component, @Service, or @Repository to register these classes in the IoC container.

When the BookController needs a BookService, Spring Boot checks the IoC container and provides the existing instance rather than creating a new one. This practice maintains a Singleton pattern by default, meaning that a single instance is shared among all classes requiring it, rather than creating fresh instances.

The true power of this method is seen when multiple components, such as AuthorController and BookService, require the same instance, like AuthorService. Spring Boot manages and shares the same instance across these classes, thereby streamlining resource utilization and maintaining consistency.


Implementing Dependency Injection in Code

To inject dependencies in Spring Boot, you annotate your classes appropriately (e.g., @Service) and use dependency injection through the constructor, ensuring Spring Boot provides the dependencies automatically. By applying this practice, you successfully separate business logic, delegating it from controllers to services, thus enhancing code organization.

For example, the BookController delegates logic to BookService, which might require AuthorService. All dependencies are managed by Spring Boot, freeing developers from the overhead of manual class instantiation.

The BookService class


@Service
public class BookService {

    private final List<Book> books = new ArrayList<>();

    public List<Book> getBooks(){
        return books;
    }

    public Book addBook(@RequestBody Book book) {
        books.add(book);
        return book;
    }

    public Book updateBook(@PathVariable Long id, @RequestBody Book updatedBook) {
        for(var book : books) {
            if(book.getId().equals(id)) {
                book.setTitle(updatedBook.getTitle());
                book.setAuthor(updatedBook.getAuthor());
            }
            return book;
        }
        return null;
    }

    public String deleteBook(@PathVariable Long id) {
        books.removeIf(book -> book.getId().equals(id));
        return "Book with id " + id + "was deleted";
    }
}
Enter fullscreen mode Exit fullscreen mode

and the BookController class


@RestController
@RequestMapping("/books")
public class BookController {
    private final BookService bookService;

    @Autowired
    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

    @GetMapping
    public List<Book> getBooks(){
        return bookService.getBooks();
    }

    @PostMapping
    public Book addBook(@RequestBody Book book) {
        return bookService.addBook(book);
    }

    @PutMapping("/{id}")
    public Book updateBook(@PathVariable Long id, @RequestBody Book updatedBook) {
        return bookService.updateBook(id, updatedBook);
    }

    @DeleteMapping("/{id}")
    public String deleteBook(@PathVariable Long id) {
        return bookService.deleteBook(id);
    }
}

Enter fullscreen mode Exit fullscreen mode

Getting Hands-On with Postman and IntelliJ IDEA

Before putting our knowledge into practice, ensure your Spring Boot application is running. You can use Postman to manage requests for your application, creating collections and executing commands like GET to retrieve book information, POST to create new entries, and PUT/DELETE to update or delete records.

Within IntelliJ IDEA, our initial setup includes a library management tool. As you refine your implementations, you should notice that more complex operations like data handling could be shifted to repositories, marked with @Repository.

Example of Postman collection


Conclusion

In conclusion, using dependency injection in Spring Boot not only promotes clean and manageable code but also enhances testability and flexibility. As we advance to the next session, we'll explore setting up databases to integrate more robust data management within our applications.

Don't forget to like and subscribe to stay updated on our latest tutorials. Thank you for joining this journey, and see you in the next part where we'll dive deeper into repositories and database setup!


Feel free to reach out if you require further insights or have queries about Spring Boot and its functionalities.

Top comments (0)