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 inject into bean properties?

A bean usually have some private properties that can be accessed through a pair of accessor methods, the setters and getters. These setters, the setXXX() method can be used by Spring Framework to configure the beans.

This method of injecting beans property through their setter methods is called the setter injection. The following example will show you how to do it.

Below is our DrawingBean that have colour and shape properties. In the example we will inject both of the properties using their respective setter method. The configuration is done in the Spring application configuration file.

package org.kodejava.spring.core;

public class DrawingBean {
    private String colour;
    private Shape shape;

    public DrawingBean() {
    }

    public void drawShape() {
        getShape().draw();
        System.out.printf("The colour is %s.", getColour());
    }

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

    public Shape getShape() {
        return shape;
    }

    public void setShape(Shape shape) {
        this.shape = shape;
    }
}

We can inject a simple value into a bean, such as string, number, etc. We can also inject a reference to another bean. Here we define an example of other bean, the Rectangle bean that we will inject into the DrawingBean.

package org.kodejava.spring.core;

public interface Shape {
    /**
     * Draw a shape.
     */
    void draw();
}
package org.kodejava.spring.core;

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle.");
    }
}

Let’s create the Spring application configuration file that will register our beans into the Spring context. After that we just create a simple program to execute it.

<?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="rectangle" class="org.kodejava.spring.core.Rectangle" />

    <bean id="drawingBean" class="org.kodejava.spring.core.DrawingBean">
        <property name="colour" value="Red" />
        <property name="shape" ref="rectangle" />
    </bean>

</beans>

In the configuration file above you can see that we use the property element to set a bean’s property. The name attribute is referring to the bean’s setter methods name, exclude the set prefix.

The value attribute of the property element is used to inject a simple value, such as string, int, etc. For injecting a reference to another bean we use the ref attribute instead.

package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DrawingBeanDemo {
    public static void main(String[] args) {
        try (var context = new ClassPathXmlApplicationContext("drawing-bean.xml")) {
            DrawingBean bean = (DrawingBean) context.getBean("drawingBean");
            bean.drawShape();
        }
    }
}

Here are the output of our example:

Drawing a rectangle.
The colour is Red.

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 a bean through constructors?

The following example demonstrate how we can inject a bean through their constructors. We will create a couple interfaces and classes for this purpose. First we will create the Singer interface and the Instrument interface. The Singer interface define a single method call sing() that will enable the implementation to sing a song.

The second interface, Instrument also define a single method call play(). This method will allow the implementation to play some instrument. After defining our example interface we create an implementation for each of them. The class will be called the AnySinger and Piano.

Here are the code that we have to code so far:

package org.kodejava.spring.core;

public interface Singer {
    /**
     * Sing a song.
     */
    void sing();
}
package org.kodejava.spring.core;

public interface Instrument {
    /**
     * Play an instrument.
     */
    void play();
}
package org.kodejava.spring.core;

public class AnySinger implements Singer {
    private String song = "Nana nana nana";
    private Instrument instrument = null;

    public AnySinger() {
    }

    /**
     * A constructor to create singer to sing a specific song.
     *
     * @param song the song title to sing.
     */
    public AnySinger(String song) {
        this.song = song;
    }

    /**
     * A constructor to create singer to sing a song while playing
     * an instrument.
     *
     * @param song       the song title to sing.
     * @param instrument the instrument to play.
     */
    public AnySinger(String song, Instrument instrument) {
        this.song = song;
        this.instrument = instrument;
    }

    @Override
    public void sing() {
        System.out.println("Singing " + song);
        if (instrument != null) {
            instrument.play();
        }
    }
}
package org.kodejava.spring.core;

public class Piano implements Instrument {

    @Override
    public void play() {
        System.out.println("Playing the Piano");
    }
}

We have created the classes that we need for our program to work. The next step is to create our spring configuration file. This will configure our bean in the spring container and wire all the dependency required by the bean.

<?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="piano" class="org.kodejava.spring.core.Piano" />

    <bean id="singer" class="org.kodejava.spring.core.AnySinger">
        <constructor-arg value="Dust in The Wind" />
        <constructor-arg ref="piano" />
    </bean>

</beans>

In the spring configuration we declare two beans. The first bean is the piano bean, which is a type of instrument. The main object of our example is the singer bean. To create the singer we use a constructor injector to inject some values or object reference for the bean to use.

In the singer bean we use the &lt;constructor-arg/&gt; element to inject dependency for the object. The value attribute can be use for passing a string or other primitive value. To pass an object reference we need to use the ref attribute.

Finally, we’ll create a simple program to run our constructed spring application. The code will include the process of loading our spring container, obtaining the bean from the container. Let’s see our singer in action.

package org.kodejava.spring.core;

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

public class SingerDemo {
    public static void main(String[] args) {
        ConfigurableApplicationContext context =
                new ClassPathXmlApplicationContext("singer.xml");

        Singer singer = (Singer) context.getBean("singer");
        singer.sing();
        context.close();
    }
}

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