What is Dependency Injection

What is Dependency Injection?

Table of Contents

Dependency Injection is a pattern that is used to remove dependency from the programming code so that it becomes easy to manage and test the application.

Dependency Lookup (DL):

It is an approach where you get the resources after demand. There are various methods to get resources.

  1. To get the resource directly by calling a new keyword.

 Example: 

A obj = new AImpl();

  1. Factory Method: By calling a static factory method.

Example:

A obj = A.getA();  

  1. Java Directory Naming Interface (JNDI): 

Example: 

Context ctx = new InitialContext();  

Context environmentCtx = (Context) ctx.lookup(“java:comp/env”);  

A obj = (A)environmentCtx.lookup(“A”);  

Problems in Dependency Lookup:

There are two main problems in this approach:

  1. Tight coupling: If a resource is changed, a lot of modification is required in the programming code.
  2. Not easy for testing: It creates a lot of problems while testing mainly in black-box testing.

Dependency Injections makes the code loosely coupled and easy for testing. An example is given below:

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:

  1. By using Constructor
  2. By using the Setter method

Dependency Injection using Constructor:

Here, the dependency can be injected using constructor and is done through the bean configuration file. The properties to be set are defined under <constructor-arg> tag in the bean configuration file.

Example:

Step 1: Book.java

public class Book {  
    private int id;  
    private String bookName;  
    public Book() {System.out.println("Java");}  
    public Book(int id) {this.id = id;}  
    public Book(String bookName) {  this.bookName = bookName;}  
    public Book(int id, String bookName) {  
        this.id = id;  
        this.bookName = bookName;  
    }  
    void display(){  
        System.out.println(id+" "+bookName);  
    }  
}

Step 2: applicationContext.java

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="https://www.springframework.org/schema/beans"  
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="https://www.springframework.org/schema/p"  
    xsi:schemaLocation="https://www.springframework.org/schema/beans  
                https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
<bean id="book" class="com.spring.example.Book">  
<constructor-arg value="1" type="int"></constructor-arg>  
</bean>  
</beans>

Step 3: Main.java

import org.springframework.beans.factory.BeanFactory;  
import org.springframework.beans.factory.xml.XmlBeanFactory;  
import org.springframework.core.io.*;  
public class Main {  
    public static void main(String[] args) {  
        Resource r=new ClassPathResource("applicationContext.xml");  
        BeanFactory factory=new XmlBeanFactory(r);  
        Book b=(Book)factory.getBean("book");  
        b.display();  
    }  
}

Dependency Injection Using Setter Method:

Here, the dependency can be injected using setter/getter methods and is done through the bean configuration file. The properties to be set are defined under the <property> tag in the bean configuration file.

Example:

Step 1: Book.java

public class Book {  
    private int id;  
    private String bookName;  
    private String author;  
    public int getId() {  
        return id;  
    }  
    public void setId(int id) {  
        this.id = id;  
    }  
    public String getBookName() {  
        return bookName;  
    }  
    public void setBookName(String bookName) {  
        this.bookName = bookName;  
    }  
    public String getAuthor() {  
        return author;  
    }  
    public void setAuthor(String author) {  
        this.author = author;  
    }  
    void display(){  
        System.out.println(id+" "+bookName+" "+author);  
    }  
}

Step 2: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="https://www.springframework.org/schema/beans"  
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="https://www.springframework.org/schema/p"  
    xsi:schemaLocation="https://www.springframework.org/schema/beans  
                https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
<bean id="book" class="com.spring.example.Book">  
<property name="id">  
<value>1</value>  
</property>  
<property name="bookName">  
<value>The Complete Reference J2EE</value>  
</property>  
<property name="author">  
<value>Herbert Schildt</value>  
</property>  
</bean>  
</beans>

Step 3: Main.java

import org.springframework.beans.factory.BeanFactory;  
import org.springframework.beans.factory.xml.XmlBeanFactory;  
import org.springframework.core.io.*;  
public class Main {  
    public static void main(String[] args) {  
        Resource r=new ClassPathResource("applicationContext.xml");  
        BeanFactory factory=new XmlBeanFactory(r);  
        Book b=(Book)factory.getBean("book");  
        b.display();  
    }  
}

Difference between Setter Dependency Injection and Constructor Dependency Injection:

Setter Dependency Injection (SDI)Constructor Dependency Injection (CDI)
Readability is poor, as there is a lot of code in the application.Readability is good as dependency is separately present in the code.
The bean should include setter and getter methods.The bean should contain a matching constructor with argument; otherwise, BeanCreationException will be thrown.
It is preferred when properties are less and contain mutable objects.It is preferred when properties are more and contain immutable objects.
There is a scope of circular dependency, and partial dependency is available.There is no scope of circular dependency or partial dependency.
It requires @Autowired annotation to increase the coupling between the classes and DI containers.It does not require the addition of @Autowired annotation.
Share this article