Friday, 29 June 2018

How to Inject Map having Dependent Object in key and value using DI by Setter method

Enjoying This Tutorial?

Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!

SUBSCRIBE NOW

Introduction

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 Department key to an Employee value) 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.


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
pom.xml

<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%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

package com.ram.model;

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

package com.ram.model;

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

package com.ram.core;

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

<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-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

package com.ram.core;

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

May 17, 2018 8:47:52 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
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:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • No comments:

    Post a Comment

    Tutorials