logo

Dependency Injection In Spring


Show

Dependency Injection (DI) is a mechanism in the Inversion of Control (IoC) of the Spring framework which is used to remove the dependency from the programming code so that it can be convenient and easy to test and manage the programming code. It makes a programming code loosely coupled. In complex applications, dependency injection helps in grouping the application classes together and at the same time makes them independent. Dependency injection of the Spring is used in a variety of enterprise Java applications, ranging from microservices, data-driven systems to web services.

Dependency Lookup

To better understand the dependency injection, we should learn the concept of Dependency Lookup. The Dependency Lookup is a way of getting the resource after demand. There are various ways to accomplish this task. Just look below:

A obj = new AImpl();

In this example, we will directly get the resource which is the instance of A class by new keyword.

We can perform the same task by using the Factory method. Take a look:

A obj = A.getA();

Here, we will get the same result but by calling the static factory method getA().

There is another way to get the resource that is by using JNDI (Java Naming Directory Interface).

Context ctx = new InitialContext();  
Context environmentCtx = (Context) ctx.lookup("java:comp/env");  
A obj = (A)environmentCtx.lookup("A");  

Let's better understand the concept of Dependency injection with a simple example. Suppose you are writing an application with a text editor component and you want a spell check functionality, then the standard code would be as below:

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

There is a dependency that has occurred between the TextEditor and the SpellChecker. In case of inversion of control, we will write a code like below:

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Now there is no need to worry about SpellChecker implementation because the implementation of the SpellChecker will be independent and the same will be provided to the TextEditor at the time of TextEditor instantiation. The spring framework will take care of this entire procedure of dependency injection.

Another example of the Dependency injection to get the instance of the class is by providing the information from an external source such as an XML file. In that case, our code would be like this:

class Employee{  
Address address;  

Employee(Address address){  
this.address=address;  
}  
public void setAddress(Address address){  
this.address=address;  
}  

} 

There are two ways to perform Dependency Injection in the Spring framework:

  • By Constructor
  • By Setter method

Now we will study both the methods in detail:

Constructor-based Dependency Injection

Constructor-based dependency injection is used when the container invokes a class constructor with many arguments where each constructor represents a dependency on the other class. Here Dependency will be injected with the help of constructors. Constructor Dependency Injection will set the DI in bean by the bean-configuration file. Here the tag in the bean-config file will take care of the property to be set with the CDI.

Now look at the example below:

package com.intellinuts;

import com.intellinuts.IGeek;

public class GFG {

    // The object of the interface IGeek
    IGeek geek;

    // Constructor to set the CDI
    GFG(IGeek geek)
    {
        this.geek = geek;
    }
}

Now you will have to set the Constructor-based Dependency Injection (CDI) in the bean-config file as below:

<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-2.5.xsd">

    <bean id="GFG" class="com.intellinuts.GFG">
        <constructor-arg>
            <bean class="com.intellinuts.impl.CsvGFG" />
        </constructor-arg>
    </bean>

<bean id="CsvGFG" class="com.intellinuts.impl.CsvGFG" />
<bean id="JsonGFG" class="com.intellinuts.impl.JsonGFG" />

</beans>

In the above code, the ‘CsvGFG’ bean is injected into the ‘GFG’ object by the setter method (‘setGeek’)

Setter-based Dependency Injection

In the case of Setter-based Dependency injection, the setter methods are called by the container on the beans after invoking a no-argument constructor/no-argument static factory method to instantiate the bean. It is a simple dependency injection method in Spring. Now you can set dependency injection as setter dependency injection through the bean-configuration file. To perform this action, the property to be set with the SDI is declared under the tag in the bean-config file.

For better understanding, take an example below:

There is a class named GFG that uses Setter based dependency injection and sets the property geeks. For this, the code will be as follows:

package com.intellinuts.com;

import com.intellinuts.com.Inuts;

public class GFG {

    // The object of the interface IGeek
    IGeek geek;

    // Setter method for property geek
    public void setGeek(IGeek geek)
    {
        this.geek = geek;
    }
}

Now to set the setter dependency injection in the bean-config file you should write the code as follows:

<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-2.5.xsd">

    <bean id="GFG" class="com.intellinuts.GFG">
        <property name="geek">
            <ref bean="CsvGFG" />
        </property>
    </bean>

<bean id="CsvGFG" class="com.intellinuts.impl.CsvGFG" />
<bean id="JsonGFG" class="com.intellinuts.impl.JsonGFG" />
         

</beans>

In the above code, the ‘CsvGFG’ bean will be injected into the ‘GFG’ object with the help of a setter method (‘setGeek’).

Setter Dependency Injection (SDI) vs. Constructor Dependency Injection (CDI)

You can use the combination of Constructor-based and Setter-based dependency injection, but it is better to use constructor arguments for mandatory dependencies and setters for optional dependencies. Now we will study the difference between the constructor and setter based dependency injection with the help from the table below:

Setter DI

Constructor DI

Readability is poor because it adds a lot of boilerplate codes to the application.

Readability is good because it presents separately in the code.

The bean has to add getter and setter methods for the properties.

Here, it is compulsory for the bean class to declare a matching constructor with arguments. Otherwise, it will throw the BeanCreationException.

It is required to add the @Autowired annotation, above the setter in the code to increase the coupling between the class and the DI container.

There is no need to add @Autowired annotation in the code because it handles the loose coupling with the DI container.

Here the object is created before the injection circular and partial dependencies will come as a result.

No chance of circular or partial dependencies because these are resolved before the creation of the object itself.

Favorable in case of fewer properties where mutable objects can be created.

Ideal for a high number of properties on the bean where immutable objects are vital for the applications.