Wednesday, 27 June 2018

How to Inject Set having Dependent Object using Spring 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, configuring collection dependencies often involves collections that must maintain uniqueness, such as a java.util.Set. When your model requires a set containing custom dependent collaborator objects rather than basic literals, Spring provides the <set> element along with <ref bean="..."/> tags to seamlessly inject them via setter-based dependency injection.

Why Inject a Set of Dependent Objects?

  • Ensuring Uniqueness: A Set guarantees that duplicate collaborator references are automatically eliminated based on the object's equals() and hashCode() contracts.
  • Declarative Collaborator Wiring: By leveraging nested <ref bean="..."/> elements inside <set>, Spring connects independent bean instances without manual code instantiation.
  • Loose Coupling: Dependent beans can be configured and managed independently in XML, making testing and maintenance straightforward.

Step-by-Step Code Example

Here is an example showing how to inject a Set<Address> of dependent objects into a Customer bean using setter injection:

1. The Dependent and Consumer Classes

package com.ram.model;

import java.util.Objects;
import java.util.Set;

// Dependent Object
public class Address {
    private String city;
    private String state;

    public void setCity(String city) {
        this.city = city;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return Objects.equals(city, address.city) && Objects.equals(state, address.state);
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, state);
    }

    @Override
    public String toString() {
        return "Address [city=" + city + ", state=" + state + "]";
    }
}

// Consumer Class holding the Set
public class Customer {
    private String name;
    private Set<Address> addresses;

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

    // Setter method for Set injection
    public void setAddresses(Set<Address> addresses) {
        this.addresses = addresses;
    }

    public void display() {
        System.out.println("Customer Name: " + name);
        System.out.println("Addresses:");
        for (Address address : addresses) {
            System.out.println(address);
        }
    }
}

2. Configuring applicationContext.xml

Define the dependent beans first, then reference them inside the <set> element:

<!-- Dependent Address Beans -->
<bean id="address1" class="com.ram.model.Address">
    <property name="city" value="Bangalore" />
    <property name="state" value="Karnataka" />
</bean>

<bean id="address2" class="com.ram.model.Address">
    <property name="city" value="Chennai" />
    <property name="state" value="Tamil Nadu" />
</bean>

<!-- Customer Bean with Set Injection -->
<bean id="customer" class="com.ram.model.Customer">
    <property name="name" value="Ram" />
    <property name="addresses">
        <set>
            <ref bean="address1" />
            <ref bean="address2" />
        </set>
    </property>
</bean>

3. Loading and Executing with ApplicationContext

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

Customer customer = (Customer) context.getBean("customer");
customer.display();

Key Takeaway

Using <set> with nested <ref bean="..."/> elements enables Spring to populate distinct collaborator beans into a Java Set using setter injection, keeping component configurations flexible and strictly organized.


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

Click the below Image to Enlarge:

How to Inject Set having Dependent Object using Spring dependency injection by Setter method

How to Inject Set having Dependent Object using Spring dependency injection by Setter method

How to Inject Set having Dependent Object using Spring dependency injection by Setter method

How to Inject Set having Dependent Object using Spring 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.Set;

import com.ram.model.Fruit;

public class FruitShop
{
    private String shopName;
    private Set<Fruit> availableFruitsSet;

    public String getShopName()
    {
        return shopName;
    }

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

    public Set<Fruit> getAvailableFruitsSet()
    {
        return availableFruitsSet;
    }

    public void setAvailableFruitsSet(Set<Fruit> availableFruitsSet)
    {
        this.availableFruitsSet = availableFruitsSet;
    }

    public void displayFruitShopInfo()
    {
        System.out.println("FruitShop [shopName=" + shopName
                + ", availableFruitsSet=" + availableFruitsSet + "]");
    }

}

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="availableFruitsSet">
            <set>
                <ref bean="fruit1" />
                <ref bean="fruit2" />
            </set>
        </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 14, 2018 10:00:02 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Mon May 14 10:00:02 IST 2018]; root of context hierarchy
May 14, 2018 10:00:02 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)
FruitShop [shopName=Fruit Mart, availableFruitsSet=[Fruit [name=Apple, color=Red], Fruit [name=Grapes, color=Violet]]]

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Setter_DI_Set_dependentObject.zip?attredirects=0&d=1

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

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