How to define a List bean in Spring?

0 votes
asked Mar 10, 2010 by guerda

I'm using Spring to define stages in my application. It's configured that the necessary class (here called Configurator) is injected with the stages.
Now I need the List of Stages in another class, named LoginBean. The Configurator doesn't offer access to his List of Stages.

I cannot change the class Configurator.

My Idea:
Define a new bean called Stages and inject it to Configurator and LoginBean. My problem with this idea is that I don't know how to transform this property:

<property ...>
  <list>
    <bean ... >...</bean>
    <bean ... >...</bean>
    <bean ... >...</bean>
  </list>
</property>

into a bean.

Something like this does not work:

<bean id="stages" class="java.util.ArrayList">

Can anybody help me with this?

9 Answers

0 votes
answered Mar 10, 2010 by stacker

Here is one method:

<bean id="stage1" class="Stageclass"/>
<bean id="stage2" class="Stageclass"/>

<bean id="stages" class="java.util.ArrayList">
    <constructor-arg>
        <list>
            <ref bean="stage1" />
            <ref bean="stage2" />                
        </list>
    </constructor-arg>
</bean>
0 votes
answered Mar 10, 2010 by simonlord

Import the spring util namespace. Then you can define a list bean as follows:

<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/util
                    http://www.springframework.org/schema/util/spring-util-2.5.xsd">


<util:list id="myList" value-type="java.lang.String">
    <value>foo</value>
    <value>bar</value>
</util:list>

The value-type is the generics type to be used, and is optional. You can also specify the list implementation class using the attribute list-class.

0 votes
answered Mar 10, 2010 by stephen-c

I think you may be looking for org.springframework.beans.factory.config.ListFactoryBean.

You declare a ListFactoryBean instance, providing the list to be instantiated as a property withe a <list> element as its value, and give the bean an id attribute. Then, each time you use the declared id as a ref or similar in some other bean declaration, a new copy of the list is instantiated. You can also specify the List class to be used.

0 votes
answered Mar 10, 2010 by juan-perez

Use the util namespace, you will be able to register the list as a bean in your application context. You can then reuse the list to inject it in other bean definitions.

0 votes
answered Mar 30, 2011 by haju

Stacker posed a great answer, I would go one step farther to make it more dynamic and use Spring 3 EL Expression.

<bean id="listBean" class="java.util.ArrayList">
        <constructor-arg>
            <value>#{springDAOBean.getGenericListFoo()}</value>
        </constructor-arg>
</bean>

I was trying to figure out how I could do this with the util:list but couldn't get it work due to conversion errors.

0 votes
answered Mar 8, 2014 by koray-tugay
<bean id="someBean"
      class="com.somePackage.SomeClass">
    <property name="myList">
        <list value-type="com.somePackage.TypeForList">
            <ref bean="someBeanInTheList"/>
            <ref bean="someOtherBeanInTheList"/>
            <ref bean="someThirdBeanInTheList"/>
        </list>
    </property>
</bean>

And in SomeClass:

class SomeClass {

    private List<TypeForList> myList;

    @Required
    public void setMyList(List<TypeForList> myList) {
        this.myList = myList;
    }

}
0 votes
answered Mar 11, 2014 by jakub-kubrynski

Another option is to use JavaConfig. Assuming that all stages are already registered as spring beans you just have to:

@Autowired
private List<Stage> stages;

and spring will automatically inject them into this list. If you need to preserve order (upper solution doesn't do that) you can do it in that way:

@Configuration
public class MyConfiguration {
  @Autowired
  private Stage1 stage1;

  @Autowired
  private Stage2 stage2;

  @Bean
  public List<Stage> stages() {
    return Lists.newArrayList(stage1, stage2);
  }
}

The other solution to preserve order is use a @Order annotation on beans. Then list will contain beans ordered by ascending annotation value.

@Bean
@Order(1)
public Stage stage1() {
    return new Stage1();
}

@Bean
@Order(2)
public Stage stage2() {
    return new Stage2();
}
0 votes
answered Mar 17, 2014 by jose-alban

As an addition to Jakub's answer, if you plan to use JavaConfig, you can also autowire that way:

import com.google.common.collect.Lists;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;

<...>

@Configuration
public class MyConfiguration {

    @Bean
    public List<Stage> stages(final Stage1 stage1, final Stage2 stage2) {
        return Lists.newArrayList(stage1, stage2);
    }
}
0 votes
answered Sep 15, 2017 by slava-babin

And this is how to inject set in some property in Spring:

<bean id="process"
      class="biz.bsoft.processing">
    <property name="stages">
        <set value-type="biz.bsoft.AbstractStage">
            <ref bean="stageReady"/>
            <ref bean="stageSteady"/>
            <ref bean="stageGo"/>
        </set>
    </property>
</bean>
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...