Enjoying This Tutorial?
Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!
SUBSCRIBE NOWIntroduction
In Spring Framework, configuring collection dependencies often involves key-value mappings where both the keys and values are custom bean references rather than primitive types. Spring provides robust XML configuration tags like <map> and <entry> with attributes such as key-ref and value-ref to inject complex java.util.Map structures using setter-based dependency injection.
Why Inject Dependent Objects in Map Keys and Values?
- Complex Domain Associations: Allows mapping distinct entity objects (e.g., a
Departmentkey to anEmployeevalue) directly through configuration. - key-ref & value-ref Attributes: Eliminates boilerplate lookup code by wiring independent Spring bean definitions into map entries seamlessly.
- Decoupled Architecture: Keeps configuration of individual collaborators modular and easily reusable across other beans in the application context.
Step-by-Step Code Example
Here is an example showing how to configure and inject a Map where both key and value are dependent collaborator objects:
1. The Model Classes
package com.ram.model;
import java.util.Map;
// Key Object
public class Department {
private String deptName;
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "Department [deptName=" + deptName + "]";
}
}
// Value Object
public class Employee {
private String empName;
public void setEmpName(String empName) {
this.empName = empName;
}
@Override
public String toString() {
return "Employee [empName=" + empName + "]";
}
}
// Consumer Class holding the Map
public class Organization {
private Map<Department, Employee> deptHeadMap;
// Setter method for map injection
public void setDeptHeadMap(Map<Department, Employee> deptHeadMap) {
this.deptHeadMap = deptHeadMap;
}
public void display() {
for (Map.Entry<Department, Employee> entry : deptHeadMap.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
2. Configuring applicationContext.xml
Use key-ref and value-ref inside the <entry> element to reference existing bean definitions:
<!-- Dependent Bean Definitions -->
<bean id="deptIT" class="com.ram.model.Department">
<property name="deptName" value="Information Technology" />
</bean>
<bean id="empRam" class="com.ram.model.Employee">
<property name="empName" value="Ram" />
</bean>
<!-- Organization Bean with Map Setter Injection -->
<bean id="organization" class="com.ram.model.Organization">
<property name="deptHeadMap">
<map>
<entry key-ref="deptIT" value-ref="empRam" />
</map>
</property>
</bean>
3. Loading and Executing the Application
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Organization org = (Organization) context.getBean("organization");
org.display();
Key Takeaway
Spring makes wiring complex data structures easy through <entry key-ref="..." value-ref="..."/>. This allows full decoupling of key and value object configurations while letting Spring's IoC container inject complete, ready-to-use maps into your beans.
Recommended Collection & Dependency Injection Tutorials from Ram N Java
Click here to watch on Youtube:
https://www.youtube.com/watch?v=tzuWplk3OF8&list=UUhwKlOVR041tngjerWxVccw
Click the below Image to Enlarge:
| How to Inject Map having Dependent Object in key and value using DI by Setter method |
| How to Inject Map having Dependent Object in key and value using DI by Setter method |
| How to Inject Map having Dependent Object in key and value using DI by Setter method |
| How to Inject Map having Dependent Object in key and value using DI by Setter method |
| How to Inject Map having Dependent Object in key and value using DI by Setter method |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0%20http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ram.core</groupId>
<artifactId>SpringDemo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringDemo</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring 5 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>
Fruit.java
public class Fruit
{
private String name;
private String color;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
@Override
public String toString()
{
return "Fruit [name=" + name + ", color=" + color + "]";
}
}
FruitSeller.java
public class FruitSeller
{
private String name;
private String emailId;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getEmailId()
{
return emailId;
}
public void setEmailId(String emailId)
{
this.emailId = emailId;
}
@Override
public String toString()
{
return "FruitSeller [name=" + name + ", emailId=" + emailId + "]";
}
}
FruitInfo.java
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.ram.model.Fruit;
import com.ram.model.FruitSeller;
public class FruitInfo
{
private Map<FruitSeller, Fruit> mapOfFruitSellerAndFruit;
public Map<FruitSeller, Fruit> getMapOfFruitSellerAndFruit()
{
return mapOfFruitSellerAndFruit;
}
public void setMapOfFruitSellerAndFruit(
Map<FruitSeller, Fruit> mapOfFruitSellerAndFruit)
{
this.mapOfFruitSellerAndFruit = mapOfFruitSellerAndFruit;
}
public void displayFruitInfo()
{
System.out.println("FruitInfo [mapOfFruitSellerAndFruit="
+ mapOfFruitSellerAndFruit + "]");
Set<Entry<FruitSeller, Fruit>> set = mapOfFruitSellerAndFruit
.entrySet();
Iterator<Entry<FruitSeller, Fruit>> itr = set.iterator();
while (itr.hasNext())
{
Entry<FruitSeller, Fruit> entry = itr.next();
System.out.println("FruitSeller = " + entry.getKey() + ", Fruit = "
+ entry.getValue());
}
}
}
applicationContext.xml
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-4.3.xsd">
<bean id="fruitSeller1" class="com.ram.model.FruitSeller">
<property name="name" value="Peter"></property>
<property name="emailId" value="Peter@yahoo.com"></property>
</bean>
<bean id="fruitSeller2" class="com.ram.model.FruitSeller">
<property name="name" value="John"></property>
<property name="emailId" value="John@gmail.com"></property>
</bean>
<bean id="fruit1" class="com.ram.model.Fruit">
<property name="name" value="Apple"></property>
<property name="color" value="Red"></property>
</bean>
<bean id="fruit2" class="com.ram.model.Fruit">
<property name="name" value="Grapes"></property>
<property name="color" value="Violet"></property>
</bean>
<bean id="fruitInfo" class="com.ram.core.FruitInfo">
<property name="mapOfFruitSellerAndFruit">
<map>
<entry key-ref="fruitSeller1" value-ref="fruit1"></entry>
<entry key-ref="fruitSeller2" value-ref="fruit2"></entry>
</map>
</property>
</bean>
</beans>
App.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App
{
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("---------------------------------------");
FruitInfo fruitInfo = (FruitInfo) context.getBean("fruitInfo");
System.out.println(
"Got fruitInfo object from the ApplicationContext(Spring container)");
fruitInfo.displayFruitInfo();
}
}
Output
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Thu May 17 08:47:52 IST 2018]; root of context hierarchy
May 17, 2018 8:47:52 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
---------------------------------------
Got fruitInfo object from the ApplicationContext(Spring container)
FruitInfo [mapOfFruitSellerAndFruit={FruitSeller [name=Peter, emailId=Peter@yahoo.com]=Fruit [name=Apple, color=Red], FruitSeller [name=John, emailId=John@gmail.com]=Fruit [name=Grapes, color=Violet]}]
FruitSeller = FruitSeller [name=Peter, emailId=Peter@yahoo.com], Fruit = Fruit [name=Apple, color=Red]
FruitSeller = FruitSeller [name=John, emailId=John@gmail.com], Fruit = Fruit [name=Grapes, color=Violet]
Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Setter_DI_Map_KVDependentObject.zip?attredirects=0&d=1
Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Setter_DI_Map_KVDependentObject
Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/00d9c316f5df8a9bcb6603e70c0baf4d24d6fdcd/Spring_2018/SpringDemo_Setter_DI_Map_KVDependentObject/?at=master
See also:
No comments:
Post a Comment