Spring Framework Setter Dependency Injection

Spring Framework Setter Dependency Injection

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

What is Setter Dependency Injection?

As illustrated in the previous article, Setter Dependency Injection in Spring is a method used to inject dependencies into Spring-managed beans. It involves providing dependencies through setter methods. In this approach, the bean class defines private fields for dependencies, and public setter methods are created to set these dependencies from external entities.

During bean initialization, the Spring container calls the setter methods and passes the configured dependencies. Setter Dependency Injection offers advantages such as flexibility, as dependencies can be changed during the object’s lifecycle, and optional dependencies can be easily managed. It enhances readability by using descriptive setter method names.

It also promotes testability as dependencies can be mocked or replaced during unit testing. However, it’s important to ensure the order of dependency setting and be mindful of potential complexity. Setter Dependency Injection in Spring enables loose coupling between classes, allowing beans to be unaware of the specifics of how their dependencies are managed. Overall, it provides a flexible and configurable approach for managing dependencies in Spring applications.

Implementing Setter Dependency Injection in Spring Framework

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

Implementing Setter Dependency Injection in Spring Framework

In this article, we will be building upon the project from the previous article (‘Spring Framework Constructor Dependency Injection’). The files and their contents should be as follows:

Kettle.java

Kettle.java

This class represents a POJO class which will be used to represent a kettle.

Drink.java
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.

App.java
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 student object and a grade object from the beans.xml file. It then prints out the objects to the terminal.

Beans.xml

Beans.xml

Step 1: Modify Kettle.java as follows:

public class Kettle
{
    private Drink drink;

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

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

We have performed the following modifications:

  1. Removed the Kettle() constructor.
  2. Added a setter method for the drink variable.

Step 2: Modify Beans.xml as follows:

<?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">
        <property name = "drink" ref = "drink"/>
   </bean>

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

We have simply replaced the code on line 8 (which used to provide the constructor argument) such that it now uses the setter.

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

Spring Framework Setter Dependency Injection with Examples

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

Benefits of using Setter Dependency Injection in Spring Framework:
  • Flexibility: Setter injection provides flexibility by allowing dependencies to be set or changed at runtime. As setter methods can be called multiple times, it becomes possible to reconfigure or switch dependencies during the lifecycle of an object.
  • Optional Dependencies: Setter injection allows for optional dependencies. Since setter methods can be invoked independently, it is possible to provide a default implementation or leave a dependency unset, giving developers the flexibility to define whether a dependency is required or not.
  • Easier Refactoring: Setter injection simplifies refactoring by reducing the impact on dependent classes. Since dependencies are set through methods, modifying the dependency or adding additional dependencies does not require changes to the class’s constructor or other classes that depend on it.
  • Loose Coupling: Setter injection promotes loose coupling between components. By depending on interfaces or abstractions rather than concrete implementations, classes become more decoupled and modular. This facilitates easier maintenance, testing, and extensibility.
  • Integration with Frameworks: Setter injection aligns well with frameworks and libraries that rely on default constructors or no-argument constructors for object creation. It allows for seamless integration with frameworks that require setter methods for property configuration.
Drawbacks of Setter Dependency Injection in Spring Framework:
  • Less Explicit: Setter injection can make the code less explicit and hide the dependencies a class requires. Since dependencies are set through methods, it may be less clear what dependencies are needed by a class, potentially leading to hidden or missing dependencies.
  • Mutable Dependencies: Setter injection allows for changing dependencies at runtime, potentially leading to mutable state within an object. This can make it more difficult to reason about the state of the object and can introduce issues related to thread safety and consistency.
  • Order of Invocation: The order in which setter methods are invoked during dependency injection can be significant. If there are dependencies with interdependencies or if the order is not correctly defined, it may result in runtime errors that are challenging to diagnose.
  • Additional Boilerplate Code: Setter injection can introduce additional boilerplate code compared to other injection approaches. Each dependency requires a corresponding setter method, leading to more lines of code and potential verbosity.
  • Potential for Incomplete Configuration: With setter injection, there is a possibility of incomplete configuration if all the required setter methods are not invoked. This can lead to runtime errors if dependencies are not properly set before using the object.

Despite these drawbacks, Setter Dependency Injection remains a widely used approach in Spring, particularly in scenarios where flexibility, optional dependencies, and runtime reconfiguration are required. It provides loose coupling, facilitates integration with other frameworks, and simplifies refactoring. However, it is essential to consider the trade-offs and use the appropriate injection approach based on the specific needs and characteristics of the application.

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

Leave a Reply

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