Spring Dependency Injection using Constructor

In previous article, we discussed about the setter injection, here we will discuss about the constructor injection.  Using Constructor Injection, makes bean class object immutable.

What’s so difference from the setter injection, actually nothing in terms of Spring bean XML configuration instead of supplying the external dependencies using property attribute this time we are going use constructor-arg attribute to provide the required dependencies. But there are few differences as well, we will see at the end of this article.

Technology Used

  • Java 1.7
  • Eclipse Kepler IDE
  • Maven 3.0.4
  • Spring-4.0.0-RELEASE

Maven-zing Spring Application

This is the simple Application using Constructor Injection to demonstrate how external dependencies are getting injected into the spring beans using declarative Spring context XML

Note: And we don’t really require the Maven here for creating build (war/ear) but having said that this helps to download the required jars from the repository. Using maven command, we can include these downloaded jars into eclipse classpath using mvn eclipse:eclipse

Add Spring-4.0.0 dependencies to the pom.xml

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>${spring.version}</version>
</dependency>

Folks who aren’t familiar with Maven concepts or don’t require maven for their project, can download the below jars individually from the spring site and include them in the classpath.

  • spring-core-4.0.0-RELEASE
  • spring-context-4.0.0-RELEASE
  • spring-beans-4.0.0-RELEASE
  • spring-aop-4.0.0-RELEASE
  • spring-expression-4.0.0-RELEASE
  • commons-logging-1.1.1
  • aopalliance-1.0

Complete pom.xml here

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>in.bench.resources</groupId>
	<artifactId>SpringAppCore</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringAppCore</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.0.0.RELEASE</spring.version>
		<java.version>1.7</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>
</project>

Let’s see coding in action

Create simple Spring beans Address and Employee

For this Constructor Dependency Injection example, we will create two classes namely Employee & Address.

Note: while working with constructor injection, there is no need of setter/getter method. But it’s a good practice to keep all the public setter/getter methods in the class.

In the Address Class, we will have one parameterized constructor with all the member variables in the constructor arguments.

Address.java

package com.spring.series.core;

public class Address {

	private String street;
	private String city;
	private String state;
	private String zipcode;

	public Address(){
		// default constructor
	}

	/**
	 * public Parameterized constructor
	 *
	 * @param street
	 * @param city
	 * @param state
	 * @param zipcode
	 */
	public Address(String street, String city, String state, String zipcode) {
		super();
		this.street = street;
		this.city = city;
		this.state = state;
		this.zipcode = zipcode;
	}

	/**
	 * getter's and setter's
	 */
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public String getZipcode() {
		return zipcode;
	}
	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	/**
	 * This method prints the address details
	 */
	public void printAddressDetail(){

		System.out.println("Address Street \t\t: " + street);
		System.out.println("Address City \t\t: " + city);
		System.out.println("Address State \t\t: " + state);
		System.out.println("Address Zip Code \t: " + zipcode);
	}
}

In Employee Class, there will be one parameterized constructor having all the member variables of the class (both simple & complex types) in the constructor arguments. This class contains a public method printEmployeeDetail() to print employee details and also invokes the public method of address class using the constructor injected ‘address’ bean object.

Note: developers can very well mix & match both Setter/Constructor Injection in the same class provided there will be one default constructor in addition to the (manually) parameterized constructor.

Employee.java

package com.spring.series.core;

public class Employee {

	private String name;
	private int age;
	private String employeeCode;
	private String designation;
	private Address address;

	public Employee(){
		// default constructor
	}

	/**
	 * public Parameterized constructor
	 *
	 * @param name
	 * @param age
	 * @param employeeCode
	 * @param designation
	 * @param address
	 */
	public Employee(String name, int age, String employeeCode,
			String designation, Address address) {
		super();
		this.name = name;
		this.age = age;
		this.employeeCode = employeeCode;
		this.designation = designation;
		this.address = address;
	}

	/**
	 * getter's and setter's
	 */
	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 getEmployeeCode() {
		return employeeCode;
	}
	public void setEmployeeCode(String employeeCode) {
		this.employeeCode = employeeCode;
	}
	public String getDesignation() {
		return designation;
	}
	public void setDesignation(String designation) {
		this.designation = designation;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}

	/**
	 * This method prints the employee details
	 */
	public void printEmployeeDetail(){

		System.out.println("Employee Name \t\t: " + name);
		System.out.println("Employee Age \t\t: " + age);
		System.out.println("Employee Code \t\t: " + employeeCode);
		System.out.println("Employee Designation \t: " + designation);

		System.out.println("\nInvoking Address object & Printing Address details\n");

		// this loc invokes method of Address class & this object is injected during spring bean instantiation
		address.printAddressDetail();
	}
}

Create Spring Bean Configuration file (Spring XML)

Configure the spring bean xml for employee bean & address bean using the element <constructor-arg> under <bean> tag.

For the dependent attribute “address” in the employee bean use <ref> attribute under <constructor-arg> to reference the complex address bean object.

SpringContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<bean id="employee" class="com.spring.series.core.Employee">
		<constructor-arg name="name" value="Mark"></constructor-arg>
		<constructor-arg name="age" value="32"></constructor-arg>
		<constructor-arg name="employeeCode" value="E10910"></constructor-arg>
		<constructor-arg name="designation" value="Software Architect"></constructor-arg>
		<constructor-arg>
			<ref bean="address" />
		</constructor-arg>
	</bean>

	<bean id="address" class="com.spring.series.core.Address">
		<constructor-arg name="street" value="Spring Office St."></constructor-arg>
		<constructor-arg name="city" value="Columbus"></constructor-arg>
		<constructor-arg name="state" value="OHIO"></constructor-arg>
		<constructor-arg name="zipcode" value="43211"></constructor-arg>
	</bean>
</beans>

Note: Name of the Spring Bean Configuration file can be anything (not necessary to have SpringContext.xml) and it’s your choice. But, in the enterprise application keep these file names appropriate to the business context. So that it will increase the readability of the application.

Project Structure in Eclipse (Package Explorer view)

ConstructorInjection

Test the Application that’s exactly …. Run it!

Having done with coding of Spring Bean (i.e.; Employee & Address classes) and configured necessary Spring bean XML and its dependent beans, it’s time to execute and see the magic of Spring Framework’s one of core features Dependency Injection (via., constructor)

Let’s test using ApplicationContext

TestEmployee.java

package com.spring.series.core;

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

public class TestEmployee {

	public static void main(String[] args) {
		testApplicationContext();
	}

	private static void testApplicationContext(){

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/spring/series/core/SpringContext.xml");
		Employee employee = (Employee) applicationContext.getBean("employee");

		System.out.println("Spring Application Demo using ApplicationContext\n");

		// invoke print() method of Employee class
		employee.printEmployeeDetail();
	}
}

Output in console

Spring Dependency Injection using Constructor

Employee Name 		: Mark
Employee Age 			: 32
Employee Code 		: E10910
Employee Designation 	: Software Architect

Invoking Address object & Printing Address details

Address Street 		: Spring Office St.
Address City 			: Columbus
Address State 		: OHIO
Address Zip Code 		: 43211

Setter Injection v/s Constructor Injection

Setter Injection  Constructor Injection
Partial injection is possible with setter injection. But it assumes that there is a default constructor provided in addition to parameterized constructor, if any. Not possible with constructor, all arguments in the constructor need to be supplied for successful instantiation of bean object.
Setter Injection makes bean object mutable i.e.; once after initialization, value of the attributes can be changed. Constructor Injection are immutable i.e.; upon successful instantiation of the bean object, value of the attributes can’t be changed.
Go for setter injection when you got both mandatory & optional attributes in your bean. Use constructor injection for mandatory attributes in your bean.
It’s quite possible to have both setter & constructor injection in your bean provided you have one default constructor in your class. In this case, setter injection overrides constructor injection. When provided both setter & constructor injection in your bean [again provided you have manually declared one default constructor] then CI gets overridden by SI.
No such prevention for Setter Injection. Constructor Injection enforces the order & completeness of the bean instantiation and prevents from possible “null” collaborators.

Download project

Spring Dependency Injection using Constructor (4kB)

Happy Coding !!
Happy Learning !!