Dependency Injection using Spring | JavaInUse



Dependency Injection using Spring



Overview


In the previous chapter we saw the Dependency Injection using Core Java. We will now implement dependency injection using Spring. The approach is similar to previous chapter but now the Spring container is responsible for the life cycle of objects. Unlike in the previous chapter the Dependency Injection functionality is implemented using the Spring Configuration File.
The design will be as follows.

This chapter makes use of Spring to explain Dependency Injection Principles.

Lets Begin

We will create Eclipse Maven project as follows-


Dependency Injection using Spring Setter Injection

For Setter Injection we will have to create the setters for all dependencies required. Unlike in chapter2, we will modify the EmployeeService.java to remove instantiation of EmployeeDAO.java using the new keyword. Also we will add setter for EmployeeDAO instance.
package com.javainuse.service;

import java.util.List;

import com.javainuse.dao.EmployeeDAO;
import com.javainuse.domain.Employee;

public class EmployeeService {
	EmployeeDAO empDAO;

	public void addNewEmployee(Employee emp) {
		empDAO.addNewEmployee(emp);
	}

	public List<Employee> getEmployees() {
		return empDAO.getAllEmployees();
	}
	
	//Setter for EmployeeDAO for setter injection
	public void setEmpDAO(EmployeeDAO empDAO) {
		this.empDAO = empDAO;
	}

}
Next we will insert the instance of EmployeeDAO.java in EmployeeService using Setter Injection.
This is done in the configuration file named as ApplicationContext.xml as follows.
property name="empDAO" ref=employeeDAO inserts the dependency in Employee Service using Setter Injection for above setter.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"  
            "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

	<!-- Create bean of type EmployeeService class and insert dependency of EmployeeDAO class in it using Setter Dependency Injection -->
	<bean id="employeeService" class="com.javainuse.service.EmployeeService">
		<property name="empDAO" ref="employeeDAO" />
	</bean>
	<!-- Create bean of type EmployeeDAO class -->
	<bean id="employeeDAO" class="com.javainuse.dao.EmployeeDAO" />
</beans>

Thus the classes are configured as beans when using Spring. These beans are then retrieved from the Spring container as follows.

package com.javainuse.main;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.javainuse.dao.EmployeeDAO;
import com.javainuse.domain.Employee;
import com.javainuse.service.EmployeeService;

public class MainApplication {

	public static void main(String[] args) {
		//Load the Spring container using the Spring Configuration File
		ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext(
				"application.xml");
				//Retrieve the Bean from the Spring Conatiner
		EmployeeService empService = container.getBean(EmployeeService.class);
		Employee emp1 = new Employee("1", "Test1", "Manager", 1000);
		Employee emp2 = new Employee("1", "Test2", "Manager", 1000);
		Employee emp3 = new Employee("1", "Test3", "Manager", 1000);
		Employee emp4 = new Employee("1", "Test4", "Manager", 1000);
		Employee emp5 = new Employee("1", "Test5", "Manager", 1000);

		empService.addNewEmployee(emp1);
		empService.addNewEmployee(emp2);
		empService.addNewEmployee(emp3);
		empService.addNewEmployee(emp4);
		empService.addNewEmployee(emp5);
		List<Employee> employees = empService.getEmployees();
		for (Employee employee : employees) {
			System.out.println(employee.getName());
		}

	}

}

When we run the program we get the output as

Dependency Injection using Spring Constructor Injection

For Constructor Injection we will have to create the constructor for all dependencies required.
Unlike in chapter2, We will modify the EmployeeService.java to remove instantiation of EmployeeDAO.java using the new keyword. Also we will add Constructor for EmployeeService which takes the argument EmployeeDAO instance.
package com.javainuse.service;

import java.util.List;

import com.javainuse.dao.EmployeeDAO;
import com.javainuse.domain.Employee;

public class EmployeeService {
	EmployeeDAO empDAO;

	public EmployeeService() {
	}
	//Constructor for EmployeeService for constructor injection
	public EmployeeService(EmployeeDAO empDAO) {
		super();
		this.empDAO = empDAO;
	}

	public void addNewEmployee(Employee emp) {
		empDAO.addNewEmployee(emp);
	}

	public List<Employee> getEmployees() {
		return empDAO.getAllEmployees();
	}

}

Next we will insert the instance of EmployeeDAO.java in EmployeeService using Constructor Injection. This is done in the configuration file named ApplicationContext.xml as follows.
constructor-arg ref="employeeDAO" inserts the dependency in Employee Service using Setter Injection for the above constructor.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"  
            "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

	<!-- Create bean of type EmployeeService class and insert dependency of EmployeeDAO class in it using Constructor Dependency Injection -->
	<bean id="employeeService" class="com.javainuse.service.EmployeeService">
		<constructor-arg ref="employeeDAO" />
	</bean>
	<bean id="employeeDAO" class="com.javainuse.dao.EmployeeDAO" />
</beans>

Thus the classes are configured as beans when using Spring. These beans are then retrieved from the Spring container as follows.

package com.javainuse.main;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.javainuse.dao.EmployeeDAO;
import com.javainuse.domain.Employee;
import com.javainuse.service.EmployeeService;

public class MainApplication {

	public static void main(String[] args) {
		// Load the Spring conatiner using the Spring Configuration File
		ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmployeeService empService = container.getBean(EmployeeService.class);
		Employee emp1 = new Employee("1", "Test1", "Manager", 1000);
		Employee emp2 = new Employee("1", "Test2", "Manager", 1000);
		Employee emp3 = new Employee("1", "Test3", "Manager", 1000);
		Employee emp4 = new Employee("1", "Test4", "Manager", 1000);
		Employee emp5 = new Employee("1", "Test5", "Manager", 1000);

		empService.addNewEmployee(emp1);
		empService.addNewEmployee(emp2);
		empService.addNewEmployee(emp3);
		empService.addNewEmployee(emp4);
		empService.addNewEmployee(emp5);
		List<Employee> employees = empService.getEmployees();
		for (Employee employee : employees) {
			System.out.println(employee.getName());
		}

	}

}

When we run the program we get the output as

Advantages of Dependency Injection using Spring-
  • The main advantage is the loose coupling between the classes. The EmployeeService and the EmployeeDAO are loosely coupled. If the EmployeeDAO is suppose replaced by another class in future then there will be no code changes required in the EmployeeService class
  • The code becomes easy to analyze as new user will not have to check where all the instances are created for the dependencies.
  • Testing of the code is easy since we can mock the classes for testing purpose.
  • Spring controls the lifecycle of the objects.
  • Spring has support for many third party frameworks like Hibernate, Apache Camel etc. Thus these can be easily integrated using Spring.


Download Source Code

Download it - Employee Management System Using Spring Setter Injection

Download it - Employee Management System Using Spring Constructor Injection

What Next?

In the next chapter will implement Traditional JDBC using Spring.