Spring Framework Constructor Dependency Injection

Spring Framework Constructor Dependency Injection

In this article, I am going to discuss Spring Framework Constructor Dependency Injection with Examples. Please read our previous article, where we discussed Spring Framework Dependency Injection.

What is Constructor Dependency Injection?

As illustrated in the previous article, Constructor Dependency Injection in Spring is an approach where dependencies are provided to a class through its constructor. When an instance of the class is created, the necessary dependencies are passed as arguments to the constructor, allowing the class to initialize its dependencies. This approach promotes loose coupling and makes dependencies explicit.

In Spring, constructor injection can be implemented using XML-based configuration, annotation-based configuration, or Java-based configuration. The Spring framework automatically resolves the dependencies and injects them when creating an instance of the class.

Constructor Dependency Injection in Spring offers benefits such as explicit dependencies, immutability, and testability. By declaring dependencies as constructor parameters, it becomes clear what dependencies are required by a class, making the code more readable and maintainable. Additionally, constructor injection allows for immutable dependencies, which can improve thread safety and prevent accidental modification. It also facilitates unit testing by enabling the easy creation of mock or stub implementations of dependencies.

Overall, constructor injection is a widely used approach in Spring as it promotes good design principles and helps build modular and maintainable applications.

Implementing Constructor Dependency Injection in Spring Framework

Before starting the project, ensure that the required JAR files are in the project’s “Referenced Libraries” folder.

Implementing Constructor Dependency Injection in Spring Framework

Step 1: Create a new file called Kettle.java in the src/ directory. Add the following lines of code to the file:

public class Kettle
{
    private Drink drink;

    public Kettle (Drink drink)
    {
        System.out.println("Putting drink into kettle: " + drink.getName());
        this.drink = drink;
    }

    public void pour()
    {System.out.println("Pouring " + drink.getName() + " into cups.");}
}

This class represents a POJO class which will be used to represent a kettle. Note that the constructor, rather than generating the Drink object itself, requires a Drink object to be provided.

Step 2: Create a new file called Drink.java in the src/ directory. Add the following lines of code to the file:

public class Drink
{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

This class represents a POJO class which will be used to represent a drink. Note that the setters and getters can be automatically added using the “Source Action…” option in the right-click menu of VS Code.

Step 3: In the src/ directory, there must be a file called App.java. Typically, this file is created automatically (when the project is created). This file contains the main() function. Modify the file as follows:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Kettle k = (Kettle) context.getBean("kettle");
        k.pour();
    }
}

The main function creates a kettle object from the beans.xml file. It then uses the pour() function to print out the object to the terminal.

Step 4: Create a new file called Beans.xml in the src/ directory. Add the following lines of code to the file:

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "kettle" class = "Kettle">
        <constructor-arg ref = "drink"/>
   </bean>

   <bean id = "drink" class = "Drink">
        <property name = "name" value = "tea"/>
   </bean>
</beans>

This file provides the parameters to create an object of type Kettle. Another bean, which generates an object of type Drink is also present. This object will be fed into the Kettle constructor.

Step 5: Compile and execute the application. Ensure compilation is successful. Ensure that the output is as expected:

Spring Framework Constructor Dependency Injection

Congratulations! You have completed the constructor dependency injection application in Spring Framework!

Benefits of using Constructor Dependency Injection in Spring Framework:
  • Explicit Dependencies: Constructor injection makes dependencies explicit. By requiring dependencies to be provided through the constructor, it becomes clear what dependencies are required by a class. This promotes clarity and reduces the chances of missing or hidden dependencies.
  • Immutability: When dependencies are injected through the constructor, they can be marked as final, making them immutable within the class. Immutable dependencies contribute to thread safety and prevent accidental modification of dependencies.
  • Testability: Constructor injection greatly facilitates unit testing. By providing dependencies through the constructor, it becomes easier to create mock or stub implementations of the dependencies during testing. This allows for better isolation and focused testing of individual components.
  • Compile-time Safety: Constructor injection provides compile-time safety because the dependencies are explicitly defined and resolved during the compilation phase. This reduces the likelihood of runtime errors caused by missing or incorrect dependencies.
  • Flexibility: Constructor injection allows for easy configuration and swapping of dependencies. By changing the implementation provided in the constructor, different behaviors or components can be seamlessly integrated into the application. This flexibility is especially valuable when working with interfaces and multiple implementation options.
Drawbacks of Constructor Dependency Injection in Spring Framework:
  • Constructor Overloading: In scenarios where a class has multiple constructors, each with different sets of dependencies, managing constructor overloading can become cumbersome. It can lead to a more complex configuration or require additional logic to determine which constructor to use.
  • Increased Boilerplate Code: Constructor injection can result in more code compared to other injection approaches. Each dependency must be declared as a constructor parameter, and additional code is required to wire and configure the dependencies.
  • Order of Dependencies: When using constructor injection, the order in which dependencies are declared in the constructor matters. This can lead to issues if dependencies have interdependencies or if the order is not correctly defined, potentially resulting in runtime errors that are difficult to diagnose.
  • Limited Flexibility in Certain Scenarios: Constructor injection may be less suitable for certain scenarios where dependencies need to be dynamically created or configured at runtime. In such cases, other injection approaches like setter injection or field injection may offer more flexibility.

Despite these drawbacks, Constructor Dependency Injection is a widely used and recommended approach in Spring due to its explicitness, immutability, and testability advantages. It promotes clearer and more maintainable code by clearly expressing dependencies, facilitating unit testing, and providing compile-time safety.

In the next article, I am going to discuss Spring Framework Setter Dependency Injection. Here, in this article, I try to explain Spring Framework Constructor Dependency Injection with Examples. I hope you enjoy this Spring Framework Constructor Dependency Injection article.

Leave a Reply

Your email address will not be published. Required fields are marked *