Secondary type dependency injection in Spring


In some previous tutorials, we have learned the dependency injection via setter and constructor and pass the primitive type values. This tutorial will help you to pass the secondary type values to setter and constructor DI.

In maximum cases, we have to inject secondary datatype. Suppose, we have Car class that has the dependency of Engine class.

public class Car {
	private Engine engine;
}

Here Engine associated with Car, then Car having one secondary datatype association.
By passing the reference, we can assign Engine class object to Car class. To do that we can use ref attribute and pass the bean id of Engine class.

Secondary type for setter

Remember for setter-based DI, use the <property/> subelement of bean tag.

Spring Beans

Create two classes as given below and associate the first class into the second class.

Engine.java
package org.websparrow.beans;

public class Engine {

	// primitive type
	private String engineNumber;
	private int modelYear;

	public String getEngineNumber() {
		return engineNumber;
	}

	public void setEngineNumber(String engineNumber) {
		this.engineNumber = engineNumber;
	}

	public int getModelYear() {
		return modelYear;
	}

	public void setModelYear(int modelYear) {
		this.modelYear = modelYear;
	}
}
Car.java
package org.websparrow.beans;

public class Car {

	private Engine engine; // secondary type
	private String carName; // primitive type

	public void setEngine(Engine engine) {
		this.engine = engine;
	}

	public void setCarName(String carName) {
		this.carName = carName;
	}

	// business logic that uses the injected values
	public void carDetails() {
		System.out.println("Car name is: " + carName);
		System.out.println("Enginer number is: " + engine.getEngineNumber());
		System.out.println("Model year is: " + engine.getModelYear());
	}
}

Spring Beans Configuration

Pass the Engine class bean id as a reference to the Car class property element.

setter-spring.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="e" class="org.websparrow.beans.Engine">
		<property name="engineNumber" value="A123GAAG" />
		<property name="modelYear" value="2018" />
	</bean>

	<bean id="c" class="org.websparrow.beans.Car">
	
		<!-- passing reference of Engine class -->
		<property name="engine" ref="e" />
		
		<property name="carName" value="Honda" />
	</bean>
	
</beans>

Execution

To execute the code we need to load the configuration file spring.xml and call them by using bean id. Here we will use the Car class bean id.

Dealer.java
package org.websparrow.common;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.websparrow.beans.Car;

public class Dealer {

	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("setter-spring.xml");

		Car c = (Car) context.getBean("c");
		c.carDetails();
	}
}
Output:

You will the following result on your console log.

Car name is: Honda
Enginer number is: A123GAAG
Model year is: 2018

Secondary type for constructor

For constructor-based DI, use the <constructor-arg/> subelement of bean tag.

Spring Beans

Similarly, you can do that for constructor based dependency injection.

Employee.java
package org.websparrow.beans;

public class Employee {

	private String empName;
	private int empMobile;

	public Employee(String empName, int empMobile) {
		this.empName = empName;
		this.empMobile = empMobile;
	}

	public String getEmpName() {
		return empName;
	}

	public int getEmpMobile() {
		return empMobile;
	}
}
Hr.java
package org.websparrow.beans;

public class Hr {

	private Employee emp; // secondary type
	private String empId; // primitive type

	public Hr(Employee emp, String empId) {
		this.emp = emp;
		this.empId = empId;
	}

	// business logic
	public void employeeDetails() {
		System.out.println("Employee id= " + empId);
		System.out.println("Employee name= " + emp.getEmpName());
		System.out.println("Employee mobile= " + emp.getEmpMobile());

	}
}

Spring Beans Configuration

Pass the Employee class bean id as a reference to the Hr class constructor-arg element.

constructor-spring.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="e" class="org.websparrow.beans.Employee">
		<constructor-arg index="0" value="Atul Rai" />
		<constructor-arg index="1" value="1234567890" />
	</bean>

	<bean id="h" class="org.websparrow.beans.Hr">
		<!-- passing reference of Employee class -->
		<constructor-arg index="0" ref="e" />
		<constructor-arg index="1" value="WSO1292" />
	</bean>

</beans>

Execution

Load the configuration file and run it.

Admin.java
package org.websparrow.common;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.websparrow.beans.Hr;

public class Admin {

	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("constructor-spring.xml");

		Hr hr = (Hr) context.getBean("h");
		hr.employeeDetails();
	}
}
Output:

You will the following result on your console log.

Employee id= WSO1292
Employee name= Atul Rai
Employee mobile= 1234567890

About the Author

Atul Rai
I like sharing my experiments and ideas with everyone by writing articles on the latest technological trends.