Categories
Spring Spring Core

Dependency Injection in Spring

Dependency Injection is a process to change the Binding of Objects from Compile time to Runtime. It focuses on creating loosely coupled objects and to make decoupling easier, Objects define their own dependent Objects and there will not be any tight-coupling between them.

IoC container is responsible to create a Dependent objects and Inject where needed.

  1. Constructor Injection
  2. Setter Injection

Are the two approaches supported by Spring Dependency Injection pattern. 

Dependency Injection in Spring

DI Flow Diagram Explanation : 

  1. IoC Container reads Bean Definition.
  2. Creates EmployeeServiceImpl Class
  3. Creates EmployeeController Class and Injects EmployeeServiceImpl Class
  4. EmployeeController class will be reference to EmployeeService Interface in it. 

Hence the contract dependency between EmployeeServiceImpl and EmployeeController class has been handled by IoC Container. In future if you want to use another implementation instead of EmployeeService means all you need is to change the Bean Definition and IoC container will create a new Object and Inject to Employee Controller. 

We will look at a simple example of Each topic of Dependency Injection here in this Article. 

We know there are two types of DI in Spring, one is Constructor based Dependency Injection and another one is Setter based Dependency Injection.

What type of Dependencies can Inject?

IoC container is capable of configuring any kind of Objects and Primitives. You can inject “int, long, String, User defined Objects, Objects from third party Library and any. 

In this example we will look at how user defined classes can be injected and make that working in Spring Dependency Injection principle.

You can also refer how Dependency Injection in Java works in this article for better understanding.

Constructor Based Dependency Injection

Injecting a Dependent Object through Constructor of a Class is called Dependency Injection. 

Let us see step by step procedure on how to create a project and add Constructor-based Dependency Injection in Detail. 

Our requirement is to add Employee Detail into the database and print the success message.

Step 1 : Java Project

Open Eclipse latest version and create a Java Project and name it as EmployeeManagement. Current latest version is “Eclipse IDE 2020 – 03 R

Step 2 : Convert to Maven Project

  1. Right click on the project name
  2. Navigate to Configure option
  3. Click on Convert to Maven Project
  4. Click finish on the pop-up window

Now your EmployeeManagement project has been converted to Maven Project.

Step 3 : Pom.xml

Open pom.xml file and add Spring Core dependencies mentioned below and save it. 

<dependencies>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.5.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>5.2.5.RELEASE</version>
		</dependency>
	</dependencies>

You can get these dependencies from the Maven repository by searching “Spring Context” and “Spring Beans” in the search bar.

Step 4 : Create Employee POJO class.

To hold the employee details create Employee POJO class under “net.geekcoders” package as below.

package net.geekcoders;

public class Employee {
	private String name;
	private int age;
	private String role;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
}

Step 5 : EmployeeService Interface

Create EmployeeService interface with addNewEmployee method under “net.geekcoders.service” package. Every service layer interaction should be passed through its base interface only.

package net.geekcoders.service;

import net.geekcoders.Employee;

public interface EmployeeService {
	boolean addNewEmployee(Employee employee);
}

Step 6 : EmployeeServiceImpl class

Create EmployeeServiceImpl class and implement EmployeeService interface. This class methods will interact with DAO layer classes or directly to the Database to save the Employee Details into the Database tables.

package net.geekcoders.service;

import net.geekcoders.Employee;

public class EmployeeServiceImpl implements EmployeeService {

	@Override
	public boolean addNewEmployee(Employee employee) {
		// Adds new employee detail in Database.
		System.out.println("New Employee added Successfully");
		return true;
	}

}

Step 7 : Controller class

Now we are going to create a Controller class, that will be the face of the application flow. IoC containers will create dependent objects and pass them to Controller class and make the application working.

package net.geekcoders.controller;

import net.geekcoders.Employee;
import net.geekcoders.service.EmployeeService;

public class EmployeeController {
	private EmployeeService employeeService;
	private Employee employee;
	
	public EmployeeController(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}	
	
	public void addNewEmployee() {
		this.getEmployeeService().addNewEmployee(employee);
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	
	public Employee getEmployee() {
		return employee;
	}
	
	public void setEmployee(Employee employee) {
		this.employee = employee;
	}
}

Here you can see the Controller class has one constructor with one EmployeeService argument in it. 

The class gets its dependent objects in the form of Constructor arguments. Earlier in the Traditional approach we will create the Dependent objects in the constructor itself by calling a new operator. That makes tight coupling between objects. 

Here in this example we are not creating an EmployeeService object,IoC container will take the responsibility to create an Object and pass it to our Constructor args.

Step 8 : Configuration Meta-Data

We are all set with Classes and Interfaces what we need for our EmployeeManagement project. Now we have to provide Bean Definition in Configuration Meta-data to make use of the IoC container to create and assemble bean objects for us. 

Create applicationContext.xml file(you can name it any) under the src folder and copy the code below.

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="employeeController" class="net.geekcoders.controller.EmployeeController">
        	<constructor-arg ref="employeeService"></constructor-arg>
        </bean>
        
        <bean id="employeeService" class="net.geekcoders.service.EmployeeServiceImpl"></bean>
</beans>

The above configuration is very simple. You are defining the EmployeeController class as a bean with “employeeController” as an identifier to make use of this bean in IoC container.

As our EmployeeController class is dependent on the EmployeeService implemented class we have to define the implementation class in a separate bean definition. (Line Number : 11)

So now employeeService object can be created from IoC container.

Now the IoC container has to inject the EmployeeServiceImpl object to EmployeeController constructor args. To make that possible we are adding a constructor-args tag under employeeController bean definition with reference to employeeService bean ID. 

Now your Constructor-based DI example program is ready, to make this application run we have to add IoC container.

Step 9 : IoC Container

This is a simple Spring Core project, to make this running we need a Starter class with the main method in it.

Create a EmployeeStarter class under “net.geekcoders” package and copy paste the below code.

By configuring the ApplicationContext interface or BeanFactory interface makes your code block as IoC Container.

package net.geekcoders;

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

import net.geekcoders.controller.EmployeeController;

public class EmployeeStarter {
	
	public static void main(String args[]) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		EmployeeController controller = applicationContext.getBean("employeeController", EmployeeController.class);
		controller.addNewEmployee();
	}
	
}

Line 1 : ClassPathXmlApplicationContext class will read “applicationContext.xml” from the class path and creates an Object for you. Objects created and managed by this ApplicationContext(IoC) container are called Spring Beans. 

Line 2 : By using the getBean method from ClassPathXmlApplicationContext class you can get the instance of EmployeeController class and assign it to EmployeeController type.

Line 3 : now you can call the method added in EmployeeController class to add new employee details.

That’s all for a Constructor-based DI pattern. Now run the above program you can see the below output in Eclipse Console.

Hurray!!!!! You have successfully created and your application is running.

Setter-based Dependency Injection

From the above example we saw Constructor-based Dependency Injection Now we will look at how to configure Setter-based Dependency Injection by slightly modifying the above program.

Step 1 : Modify Controller Class

Go to EmployeeController class and remove its constructor. We already generated getters and setters for EmployeeService dependent objects so we don’t want to add any new setter method here. If you are not having a setter and getter method implemented in your controller class please add one. 

In setter based injection IoC Container will Inject its dependencies in setter method only. 

After removing the constructor your EmployeeController class will look like this.

package net.geekcoders.controller;

import net.geekcoders.Employee;
import net.geekcoders.service.EmployeeService;

public class EmployeeController {
	private EmployeeService employeeService;
	private Employee employee;
	
	public void addNewEmployee() {
		this.getEmployeeService().addNewEmployee(employee);
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	
	public Employee getEmployee() {
		return employee;
	}
	
	public void setEmployee(Employee employee) {
		this.employee = employee;
	}
}

Step 2 : Modify Configuration Meta-Data 

Now we have to modify our applicationContext.xml file bean definition for “employeeController” definition to pass the Object through Setter instead of Constructor as like below.

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="employeeController" class="net.geekcoders.controller.EmployeeController">
			<property name="employeeService" ref="employeeService"></property>
        </bean>
        
        <bean id="employeeService" class="net.geekcoders.service.EmployeeServiceImpl"></bean>
</beans>

It’s very simple is it? That’s Spring Framework for you. 

The property tag refers to the variables with getters and setters in your controller. Using the ref attribute here IoC will get the object of “employeeService” definition and pass it to the “employeeService” property of EmployeeController. 

Save the project and run. You can see the same output in the console as before. 

That’s all for now on the Spring Dependency Injection example Article!!!

Please share if it is useful and comment if you have any doubt in it. 

Thanks for reading!!!

5 replies on “Dependency Injection in Spring”

Leave a Reply

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