S02L02 – Dependency injection continues

Understanding Dependency Injection with Practical Examples

Table of Contents

1. Introduction

Dependency Injection (DI) is a core concept in modern Java development, especially within frameworks like Spring. It helps in achieving loose coupling, making the code more modular, testable, and easier to maintain.

This article will walk you through the basics of Dependency Injection in Java. We’ll cover what it is, why it’s important, and showcase a practical example from a Java project. By the end of this article, you will have a clear understanding of how DI can simplify Java applications.

2. What is Dependency Injection?

Dependency Injection is a design pattern used to implement Inversion of Control (IoC). It allows a class to receive its dependencies from an external source, rather than creating them internally. In Java, this concept is widely used in frameworks such as Spring and CDI (Contexts and Dependency Injection) to build scalable and maintainable applications.

Dependency Injection promotes loose coupling between classes and components. There are three primary ways to implement DI:

  • Constructor Injection
  • Setter Injection
  • Field Injection
Type of Injection Description When to Use
Constructor Injection Dependencies are provided through a class constructor When all dependencies are mandatory
Setter Injection Dependencies are provided via setter methods When some dependencies are optional
Field Injection Dependencies are injected directly into fields Used primarily in frameworks, not recommended

3. Types of Dependency Injection

In this project, constructor injection is used. This is evident from the Java classes like Corolla.java and Swift.java, where the dependencies are passed via constructors.

AppConfig.java plays a central role in configuring these beans using the Spring framework’s dependency injection mechanism.

4. Code Walkthrough

App.java

Explanation:

  • This is the main entry point for the application.
  • The AnnotationConfigApplicationContext is used to load the Spring configuration defined in AppConfig.java.
  • The car object is retrieved from the Spring container, and its specs() method is called.

AppConfig.java

Explanation:

  • This class defines Spring beans for the application. Here, two beans are registered: Corolla and Swift.
  • The @Bean annotation specifies that these methods will return beans managed by the Spring container.

Car.java (Interface)

Explanation:

This is a simple interface with a specs() method that is implemented by Corolla.java and Swift.java.

Corolla.java

Explanation:

The Corolla class implements the Car interface and provides an implementation for the specs() method.

Swift.java

Explanation:

Similar to Corolla.java, Swift.java also implements the Car interface and provides a different implementation of the specs() method.

5. Benefits of Dependency Injection

  • Improved Testability: With DI, you can easily mock dependencies for unit testing.
  • Loose Coupling: The components of the application are loosely coupled, improving flexibility.
  • Easier Maintenance: Managing dependencies externally simplifies application maintenance and scaling.

6. Conclusion

Dependency Injection is a powerful design pattern that improves the modularity and flexibility of your Java applications. By using Spring’s DI capabilities, you can manage your application’s dependencies with ease. The provided example demonstrated how Spring’s configuration and beans work together to create loosely coupled applications.