How do I inject collections using map element in Spring?

In this example you will see how to wire map collections. For this purpose we can use the <map> element in the Spring configuration file. This element declares the java.util.Map. We will reuse the bean that we use in the previous example How do I inject collections using list element in Spring?.

The <map> element can have many <entry> element with the key and value-ref attribute.

Here is the configuration example:

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

    <bean id="song1" class="org.kodejava.spring.core.Song">
        <property name="title" value="I Saw Her Standing There" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song2" class="org.kodejava.spring.core.Song">
        <property name="title" value="Misery" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song3" class="org.kodejava.spring.core.Song">
        <property name="title" value="Anna (Go to Him)" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="publisher" class="org.kodejava.spring.core.Publisher">
        <property name="name" value="EMI Studios" />
    </bean>

    <bean id="album" class="org.kodejava.spring.core.Album">
        <property name="title" value="Please Please Me" />
        <property name="year" value="1963" />
        <property name="publisher">
            <map>
                <entry key="publisher" value-ref="publisher" />
            </map>
        </property>
    </bean>

</beans>

The <map> element can have many <entry> elements. We can use the key attribute to use a string as its key. If you want the key to be a reference to other bean in the Spring context you can use the key-ref instead.

The value-ref is used to set the value to refer to another bean. If the value is a simple value such as string you can use the value attribute.

To run it creates the following program:

package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoMap {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("collection-map.xml")) {
            Album album = (Album) context.getBean("album");
            System.out.println("Album = " + album);
        }
    }
}

And here what you’ll get on the console:

Album = Album{title='Please Please Me', year=1963, songs=[], publisher={publisher=Publisher{name=EMI Studios}}, props={}}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I inject collections using set element in Spring?

In this example you will see how to use the <set> element to wire a collection property of a bean. We will reuse the bean that we use in the previous example How do I inject collections using list element in Spring?.

The Album bean have a songs property that have a type of java.util.List. The <set> element does not have to be used with java.util.Set. It can be used to wire a java.util.List collection. It just means it cannot contain duplicate values in it, so the collection will only contain a unique values.

Here how we configure our Spring context:

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

    <bean id="song1" class="org.kodejava.spring.core.Song">
        <property name="title" value="I Saw Her Standing There" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song2" class="org.kodejava.spring.core.Song">
        <property name="title" value="Misery" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song3" class="org.kodejava.spring.core.Song">
        <property name="title" value="Anna (Go to Him)" />
        <property name="writer" value="Beatles" />
    </bean>


    <bean id="album" class="org.kodejava.spring.core.Album">
        <property name="title" value="Please Please Me" />
        <property name="year" value="1963" />
        <property name="songs">
            <set>
                <ref bean="song1" />
                <ref bean="song1" />
                <ref bean="song1" />
            </set>
        </property>
    </bean>

</beans>

The <set> configuration can bee seen in the album bean configuration. We set the songs property. Within this property element we use the <set> element. And then using the <ref> element we add some bean into the collection.

Create the following code to run it:

package org.kodejava.spring.core;

public class Song {
    private String title;
    private String writer;

    public Song() {
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }

    @Override
    public String toString() {
        return "Song{" +
                "title='" + title + '\'' +
                ", writer='" + writer + '\'' +
                '}';
    }
}
package org.kodejava.spring.core;

public class Publisher {
    private String name;

    public Publisher() {
    }

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

    @Override
    public String toString() {
        return "Publisher{" +
                "name=" + name +
                '}';
    }
}
package org.kodejava.spring.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Album {
    private String title;
    private int year;
    private List<Song> songs = new ArrayList<>();
    private Map<String, Publisher> publisher = new HashMap<>();
    private Properties props = new Properties();

    public Album() {
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void setSongs(List<Song> songs) {
        this.songs = songs;
    }

    public void setPublisher(Map<String, Publisher> publisher) {
        this.publisher = publisher;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    @Override
    public String toString() {
        return "Album{" +
                "title='" + title + '\'' +
                ", year=" + year +
                ", songs=" + songs +
                ", publisher=" + publisher +
                ", props=" + props +
                '}';
    }
}
package org.kodejava.spring.core;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoSet {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = 
                new ClassPathXmlApplicationContext("collection-set.xml");

        Album album = (Album) context.getBean("album");
        System.out.println("Album = " + album);
        context.close();
    }
}

You’ll see the following output in the screen. As you can see, although we set three beans into the songs property, the Album bean only contain a one song. This is because we use the <set> element to wire the collection. It does not allow duplicate values.

Album = Album{title='Please Please Me', year=1963, songs=[Song{title='I Saw Her Standing There', writer='Beatles'}], publisher={}, props={}}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I inject collections using list element in Spring?

The following example show you how to use the <list> element to wire collection property. We can use it to wire property of either arrays or some implementation of java.util.Collection such as java.util.ArrayList.

For this example we will create a bean called Album that have a collection of Song beans in it. So here is our bean classes.

package org.kodejava.spring.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Album {
    private String title;
    private int year;
    private List<Song> songs = new ArrayList<>();
    private Map<String, Publisher> publisher = new HashMap<>();
    private Properties props = new Properties();

    public Album() {
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void setSongs(List<Song> songs) {
        this.songs = songs;
    }

    public void setPublisher(Map<String, Publisher> publisher) {
        this.publisher = publisher;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    @Override
    public String toString() {
        return "Album{" +
                "title='" + title + '\'' +
                ", year=" + year +
                ", songs=" + songs +
                ", publisher=" + publisher +
                ", props=" + props +
                '}';
    }
}
package org.kodejava.spring.core;

public class Song {
    private String title;
    private String writer;

    public Song() {
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }

    @Override
    public String toString() {
        return "Song{" +
                "title='" + title + '\'' +
                ", writer='" + writer + '\'' +
                '}';
    }
}
package org.kodejava.spring.core;

public class Publisher {
    private String name;

    public Publisher() {
    }

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

    @Override
    public String toString() {
        return "Publisher{" +
                "name=" + name +
                '}';
    }
}

Here is the Spring configuration file, CollectionList.xml.

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

    <bean id="song1" class="org.kodejava.spring.core.Song">
        <property name="title" value="I Saw Her Standing There" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song2" class="org.kodejava.spring.core.Song">
        <property name="title" value="Misery" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song3" class="org.kodejava.spring.core.Song">
        <property name="title" value="Anna (Go to Him)" />
        <property name="writer" value="Beatles" />
    </bean>


    <bean id="album" class="org.kodejava.spring.core.Album">
        <property name="title" value="Please Please Me" />
        <property name="year" value="1963" />
        <property name="songs">
            <list>
                <ref bean="song1" />
                <ref bean="song2" />
                <ref bean="song3" />
            </list>
        </property>
    </bean>

</beans>

The part of the configuration that wire the song collection is inside the album bean. You can see that we have a property name songs. This property has a <list> element that contains a couple <ref> elements referring to some Song type beans.

Now let’s run it with the following code:

package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoList {
    public static void main(String[] args) {
        var context = new ClassPathXmlApplicationContext("collection-list.xml");

        Album album = (Album) context.getBean("album");
        System.out.println("Album = " + album);
        context.close();
    }
}

You’ll see the following output when you run the program:

Album = Album{title='Please Please Me', year=1963, songs=[Song{title='I Saw Her Standing There', writer='Beatles'}, Song{title='Misery', writer='Beatles'}, Song{title='Anna (Go to Him)', writer='Beatles'}], publisher={}, props={}}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I inject collections properties in Spring?

Beside injecting a simple value (using the value attribute) and a reference to other bean (using the ref attribute). We can also inject collections properties into a bean.

Spring provides four ways to inject collections. There are <list> and <set> that can be used to inject arrays or any implementation of java.util.Collection. The <map> that can be used to inject property of type java.util.Map. And the <props> can be used to inject property of type java.util.Properties.

Here is a table that summarize the collection configuration support in Spring.

Collection Element Description
<list> Wiring a list of values, where the values might have duplicates.
<set> Wiring a set of values, where the values can not have duplicates.
<map> Wiring a key-value pairs collection, where the key and value can be any type
<props> Wiring a key-value pairs property, where the key and value are both type of String

You can see the following example on how to use each type of this collection configuration:

How do I wire properties with Spring’s p namespace?

Beside using the <property> element, Spring framework also provide us another way to wiring value or reference into the bean. We can use the Spring’s p namespaces. The p namespace has a schema URI of `http://www.springframework.org/schema/p`.

With this namespace declared in the Spring configuration file you can use the p: prefixed attribute of the <bean> element to wire bean’s property.

We update the configuration used in the previous example How do I inject into bean properties? to use the p namespace. Here is the new Spring’s configuration file.

<?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.xsd">

    <bean id="rectangle" class="org.kodejava.spring.core.Rectangle" />

    <bean id="drawingBean" class="org.kodejava.spring.core.DrawingBean" p:colour="Red" p:shape-ref="rectangle" />

</beans>

The p:color attribute set the color property to Red, this is a simple value. To set the shape property we use the p:shape-ref attribute. The -ref suffix tell Spring that we are injecting a reference.

You can use the <property> element or using the p namespace to inject bean’s property. Both of them have the same functionality.

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central