Friday, 29 June 2018

How to Inject Map having Dependent Object in value using dependency injection 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 applications, configuring a java.util.Map where the key is a simple literal (such as a String) and the value is a custom dependent object bean reference is a very common scenario. Spring makes this simple and expressive in XML using the <map> and <entry> tags along with the key and value-ref attributes via setter-based dependency injection.

Why Inject Dependent Objects in Map Values?

  • Key-Based Bean Lookup: Allows mapping straightforward string keys (like department codes or role titles) directly to complex collaborator beans.
  • value-ref Attribute: Seamlessly wires independent Spring bean definitions as map values without writing custom population code.
  • Clean Separation: Allows collaborator beans to be declared independently and injected into maps across multiple beans cleanly.

Step-by-Step Code Example

Here is an example showing how to inject a Map<String, Employee> where the value is a dependent Employee bean:

1. The Model Classes

package com.ram.model;

import java.util.Map;

// Dependent Object (Value)
public class Employee {
    private String name;
    private String role;

    public void setName(String name) {
        this.name = name;
    }

    public void setRole(String role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + ", role=" + role + "]";
    }
}

// Consumer Class holding the Map
public class Organization {
    private Map<String, Employee> employeesMap;

    // Setter method for dependency injection
    public void setEmployeesMap(Map<String, Employee> employeesMap) {
        this.employeesMap = employeesMap;
    }

    public void display() {
        for (Map.Entry<String, Employee> entry : employeesMap.entrySet()) {
            System.out.println("Key: " + entry.getKey() + " -> " + entry.getValue());
        }
    }
}

2. Configuring applicationContext.xml

Use key for the string identifier and value-ref to point to the dependent bean definition:

<!-- Dependent Bean Definitions -->
<bean id="emp1" class="com.ram.model.Employee">
    <property name="name" value="Ram" />
    <property name="role" value="Technical Lead" />
</bean>

<bean id="emp2" class="com.ram.model.Employee">
    <property name="name" value="Peter" />
    <property name="role" value="Developer" />
</bean>

<!-- Organization Bean with Map Setter Injection -->
<bean id="organization" class="com.ram.model.Organization">
    <property name="employeesMap">
        <map>
            <entry key="LEAD" value-ref="emp1" />
            <entry key="DEV" value-ref="emp2" />
        </map>
    </property>
</bean>

3. Loading and Executing with ApplicationContext

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

Organization org = (Organization) context.getBean("organization");
org.display();

Key Takeaway

Configuring <entry key="..." value-ref="..."/> provides a clean and readable pattern to map literal keys to full Spring-managed bean instances through setter injection, keeping your application modular and maintainable.


Click here to watch on Youtube:
https://www.youtube.com/watch?v=ImiOMkRaARU&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:

How to Inject Map having Dependent Object in value using dependency injection by Setter method?

How to Inject Map having Dependent Object in value using dependency injection by Setter method?

How to Inject Map having Dependent Object in value using dependency injection by Setter method?

How to Inject Map having Dependent Object in value using dependency injection by Setter method?

How to Inject Map having Dependent Object in value using dependency injection 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 + "]";
    }

}

FruitShop.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;

public class FruitShop
{
    private String shopName;
    private Map<Integer, Fruit> mapOfAvailableFruits;

    public String getShopName()
    {
        return shopName;
    }

    public void setShopName(String shopName)
    {
        this.shopName = shopName;
    }

    public Map<Integer, Fruit> getMapOfAvailableFruits()
    {
        return mapOfAvailableFruits;
    }

    public void setMapOfAvailableFruits(
            Map<Integer, Fruit> mapOfAvailableFruits)
    {
        this.mapOfAvailableFruits = mapOfAvailableFruits;
    }

    public void displayFruitShopInfo()
    {
        System.out.println("Fruit ShopName = " + shopName);

        Set<Entry<Integer, Fruit>> set = mapOfAvailableFruits.entrySet();
        Iterator<Entry<Integer, Fruit>> itr = set.iterator();
        while (itr.hasNext())
        {
            Entry<Integer, Fruit> entry = itr.next();
            System.out.println("Fruit Id = " + entry.getKey()
                    + ", Fruit Info = " + 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="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="fruitShop" class="com.ram.core.FruitShop">

        <property name="shopName" value="Fruit Mart"></property>
        <property name="mapOfAvailableFruits">
            <map>
                <entry key="1" value-ref="fruit1"></entry>
                <entry key="2" 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("---------------------------------------");

        FruitShop fruitShop = (FruitShop) context.getBean("fruitShop");
        System.out.println(
                "Got fruitShop object from the ApplicationContext(Spring Container)");
        fruitShop.displayFruitShopInfo();
    }

}

Output

May 16, 2018 9:01:22 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Wed May 16 09:01:22 IST 2018]; root of context hierarchy
May 16, 2018 9:01:22 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
---------------------------------------
Got fruitShop object from the ApplicationContext(Spring Container)
Fruit ShopName = Fruit Mart
Fruit Id = 1, Fruit Info = Fruit [name=Apple, color=Red]
Fruit Id = 2, Fruit Info = 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_ValueDependentObject.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Setter_DI_Map_ValueDependentObject

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/00d9c316f5df8a9bcb6603e70c0baf4d24d6fdcd/Spring_2018/SpringDemo_Setter_DI_Map_ValueDependentObject/?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