Constructor Dependency Injection with Collection of custom Object
In some scenarios, we may need to inject a Collection of our own custom object /user defined object to another object rather than just a single object.
In such cases, we inject a Collection of custom type through a constructor.
Collection could be either List or Set but most of the requirements are best fit with List
Consider the example where Person has permanent and current addresses.
In this case, we are required to inject List of Address to person object.
Let us see the same in spring through Constructor Dependency Injection
Create a class called Person
It contains 3 attributes id,name and addresses where addresses is a list of Address type
It also contains showPersonAddresses() method to display the list of addresses that we have injected to the person object.
- package com.kb.di;
- import java.util.List;
- public class Person {
- private int id;
- private String name;
- private List<Address> addresses;
- public Person(int id, String name, List<Address> addresses) {
- super();
- this.id = id;
- this.name = name;
- this.addresses = addresses;
- }
- public void showPersonAddresses(){
- for (Address address : addresses) {
- System.out.println(address.toString());
- }
- }
- }
package com.kb.di; import java.util.List; public class Person { private int id; private String name; private List<Address> addresses; public Person(int id, String name, List<Address> addresses) { super(); this.id = id; this.name = name; this.addresses = addresses; } public void showPersonAddresses(){ for (Address address : addresses) { System.out.println(address.toString()); } } }
Create a class called Address
- package com.kb.di;
- public class Address {
- private int houseNo;
- private String streetName;
- private String city;
- private String postalCode;
- public Address(int houseNo, String streetName, String city, String postalCode) {
- super();
- this.houseNo = houseNo;
- this.streetName = streetName;
- this.city = city;
- this.postalCode = postalCode;
- }
- @Override
- public String toString() {
- return "House No-> " + houseNo + " Street Name-> " + streetName + " City->" + city + " Postal Code->"
- + postalCode;
- }
- }
package com.kb.di; public class Address { private int houseNo; private String streetName; private String city; private String postalCode; public Address(int houseNo, String streetName, String city, String postalCode) { super(); this.houseNo = houseNo; this.streetName = streetName; this.city = city; this.postalCode = postalCode; } @Override public String toString() { return "House No-> " + houseNo + " Street Name-> " + streetName + " City->" + city + " Postal Code->" + postalCode; } }
Create a spring bean definition file
In this file, we used < constructor-arg > tag with < list > to define the list of Address
< ref bean=”beanId” > tag is used to inject the bean of custom type which is Address in this case,
Where ‘beanId’ is the id of custom bean
- <?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:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
- <bean id="person" class="com.kb.di.Person">
- <constructor-arg value="1" type="int"/>
- <constructor-arg value="Raj"/>
- <constructor-arg>
- <list>
- <ref bean="permamentAdd"/>
- <ref bean="currentAdd"/>
- </list>
- </constructor-arg>
- </bean>
- <bean id="permamentAdd" class="com.kb.di.Address">
- <constructor-arg value="33" type="int"/>
- <constructor-arg value="M G Road"/>
- <constructor-arg value="Bangalore"/>
- <constructor-arg value="560001"/>
- </bean>
- <bean id="currentAdd" class="com.kb.di.Address">
- <constructor-arg value="44" type="int"/>
- <constructor-arg value="Residency Road"/>
- <constructor-arg value="Mumbai"/>
- <constructor-arg value="400051"/>
- </bean>
- </beans>
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="person" class="com.kb.di.Person"> <constructor-arg value="1" type="int"/> <constructor-arg value="Raj"/> <constructor-arg> <list> <ref bean="permamentAdd"/> <ref bean="currentAdd"/> </list> </constructor-arg> </bean> <bean id="permamentAdd" class="com.kb.di.Address"> <constructor-arg value="33" type="int"/> <constructor-arg value="M G Road"/> <constructor-arg value="Bangalore"/> <constructor-arg value="560001"/> </bean> <bean id="currentAdd" class="com.kb.di.Address"> <constructor-arg value="44" type="int"/> <constructor-arg value="Residency Road"/> <constructor-arg value="Mumbai"/> <constructor-arg value="400051"/> </bean> </beans>
If we need to inject Set rather than List, just change the above < list > tag to < set > tag.
And also make the addresses as Set in Person class instead of List
Create a pom.xml file
- <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>Spring</groupId>
- <artifactId>SpringCore</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>SpringCore</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.2.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </project>
<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>Spring</groupId> <artifactId>SpringCore</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringCore</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
Create a ConstructorDI class
This class loads the spring beans using application context and calls the person class method to display the list of addresses.
- package com.kb.di;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.beans.factory.xml.XmlBeanFactory;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.core.io.Resource;
- public class ConstructorDI {
- public static void main(String[] args) {
- ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
- Person person = (Person)applicationContext.getBean("person");
- person.showPersonAddresses();
- }
- }
package com.kb.di; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class ConstructorDI { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml"); Person person = (Person)applicationContext.getBean("person"); person.showPersonAddresses(); } }
Run the ConstructorDI class and see the output as below