Constructor Dependency Injection with Map of Custom type Example
In some scenarios, we may need to inject a map of object or map of non string object to another object.
In such cases, we inject a map of object through a constructor.
however this kind of requirements comes very rarely in real time.
Consider the example where Person has an answer sheet which includes Question and Answer.
In this case, let us use Map which stores Question type as a key and Answer type as a value.
Let us see the same in spring through Constructor Dependency Injection
Create a class called Person
It contains 3 attributes id,name and answerSheet where answerSheet is a Map of object.
It also contains showAnswerSheet () method to display the question and answers injected to the person object.
- package com.kb.di;
- import java.util.Map;
- import java.util.Map.Entry;
- public class Person {
- private int id;
- private String name;
- private Map<Question, Answer> answerSheet;
- public Person(int id, String name, Map<Question, Answer> answerSheet) {
- super();
- this.id = id;
- this.name = name;
- this.answerSheet = answerSheet;
- }
- public void showAnswerSheet(){
- for (Entry<Question, Answer> entry : answerSheet.entrySet()) {
- System.out.println(entry.getKey().getName()+"-->"+entry.getValue().getName());
- }
- }
- }
package com.kb.di; import java.util.Map; import java.util.Map.Entry; public class Person { private int id; private String name; private Map<Question, Answer> answerSheet; public Person(int id, String name, Map<Question, Answer> answerSheet) { super(); this.id = id; this.name = name; this.answerSheet = answerSheet; } public void showAnswerSheet(){ for (Entry<Question, Answer> entry : answerSheet.entrySet()) { System.out.println(entry.getKey().getName()+"-->"+entry.getValue().getName()); } } }
Create a class called Question
- package com.kb.di;
- public class Question {
- int id;
- String name;
- public Question(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
package com.kb.di; public class Question { int id; String name; public Question(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Create a class called Answer
- package com.kb.di;
- public class Answer {
- int id;
- String name;
- public Answer(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
package com.kb.di; public class Answer { int id; String name; public Answer(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Create a spring bean definition file
In this file, we used < constructor-arg > tag with < map > to define the answerSheets
< entry > tag is used to inject Map’s key and value.
< key-ref > is used to reference the key defined as a bean
< value-ref > is used to reference the value defined as a 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>
- <map>
- <entry key-ref ="question1" value-ref="answer1"/>
- <entry key-ref="question2" value-ref="answer2"/>
- <entry key-ref="question3" value-ref="answer3"/>
- </map>
- </constructor-arg>
- </bean>
- <bean id="question1" class="com.kb.di.Question">
- <constructor-arg value="1" type="int"/>
- <constructor-arg value="what is java"/>
- </bean>
- <bean id="question2" class="com.kb.di.Question">
- <constructor-arg value="2" type="int"/>
- <constructor-arg value="what is c++"/>
- </bean>
- <bean id="question3" class="com.kb.di.Question">
- <constructor-arg value="3" type="int"/>
- <constructor-arg value="what is c"/>
- </bean>
- <bean id="answer1" class="com.kb.di.Answer">
- <constructor-arg value="1" type="int"/>
- <constructor-arg value="java is object oriented langauge"/>
- </bean>
- <bean id="answer2" class="com.kb.di.Answer">
- <constructor-arg value="2" type="int"/>
- <constructor-arg value="c++ is also object oriented langauge"/>
- </bean>
- <bean id="answer3" class="com.kb.di.Answer">
- <constructor-arg value="3" type="int"/>
- <constructor-arg value="c is procedural oriented language"/>
- </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> <map> <entry key-ref ="question1" value-ref="answer1"/> <entry key-ref="question2" value-ref="answer2"/> <entry key-ref="question3" value-ref="answer3"/> </map> </constructor-arg> </bean> <bean id="question1" class="com.kb.di.Question"> <constructor-arg value="1" type="int"/> <constructor-arg value="what is java"/> </bean> <bean id="question2" class="com.kb.di.Question"> <constructor-arg value="2" type="int"/> <constructor-arg value="what is c++"/> </bean> <bean id="question3" class="com.kb.di.Question"> <constructor-arg value="3" type="int"/> <constructor-arg value="what is c"/> </bean> <bean id="answer1" class="com.kb.di.Answer"> <constructor-arg value="1" type="int"/> <constructor-arg value="java is object oriented langauge"/> </bean> <bean id="answer2" class="com.kb.di.Answer"> <constructor-arg value="2" type="int"/> <constructor-arg value="c++ is also object oriented langauge"/> </bean> <bean id="answer3" class="com.kb.di.Answer"> <constructor-arg value="3" type="int"/> <constructor-arg value="c is procedural oriented language"/> </bean> </beans>
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 Answer Sheet of a person.
- package com.kb.di;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class ConstructorDI {
- public static void main(String[] args) {
- ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
- Person person = (Person)applicationContext.getBean("person");
- person.showAnswerSheet();
- }
- }
package com.kb.di; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ConstructorDI { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml"); Person person = (Person)applicationContext.getBean("person"); person.showAnswerSheet(); } }
Run the ConstructorDI class and see the output as below
Very simple and excellent article