How to define a List bean in Spring?

JavaSpring

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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>

Solution 3 - Java

<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 {
    
    List<TypeForList> myList;
  
    @Required
    public void setMyList(List<TypeForList> myList) {
        this.myList = myList;
    }

}

Solution 4 - Java

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();
}

Solution 5 - Java

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.

Solution 6 - Java

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.

Solution 7 - Java

 <bean id="student1" class="com.spring.assin2.Student">  
<property name="name" value="ram"></property>  
<property name="id" value="1"></property> 
<property name="listTest">
        <list value-type="java.util.List">
            <ref bean="test1"/>
            <ref bean="test2"/>
        </list>
    </property>
</bean>  

define those beans(test1,test2) afterwards :)

Solution 8 - Java

Inject list of strings.

Suppose you have Countries model class that take list of strings like below.

public class Countries {
	private List<String> countries;

 	public List<String> getCountries() {
  		return countries;
 	}	

 	public void setCountries(List<String> countries) {
  		this.countries = countries;
 	}

}

Following xml definition define a bean and inject list of countries.

<bean id="demoCountryCapitals" name="demoCountryCapitals" class="com.sample.pojo.Countries">
   <property name="countries">
      <list>
         <value>Iceland</value>
         <value>India</value>
         <value>Sri Lanka</value>
         <value>Russia</value>
      </list>
   </property>
</bean>

Reference link

Inject list of Pojos

Suppose if you have model class like below.

public class Country {
	private String name;
 	private String capital;
 	.....
 	.....
 }

public class Countries {
 	private List<Country> favoriteCountries;

 	public List<Country> getFavoriteCountries() {
  		return favoriteCountries;
 	}

 	public void setFavoriteCountries(List<Country> favoriteCountries) {
  		this.favoriteCountries = favoriteCountries;
 	}

}

Bean Definitions.

 <bean id="india" class="com.sample.pojo.Country">
  <property name="name" value="India" />
  <property name="capital" value="New Delhi" />
 </bean>

 <bean id="russia" class="com.sample.pojo.Country">
  <property name="name" value="Russia" />
  <property name="capital" value="Moscow" />
 </bean>


 <bean id="demoCountryCapitals" name="demoCountryCapitals" class="com.sample.pojo.Countries">
  <property name="favoriteCountries">
   <list>
    <ref bean="india" />
    <ref bean="russia" />
   </list>
  </property>
 </bean>

Reference Link.

Solution 9 - Java

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.

Solution 10 - Java

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);
    }
}

Solution 11 - Java

You just remove id out of beans inside <list> tag. Like this:

<property name="listStaff">
  <list>
    <bean class="com.test.entity.Staff">
        <constructor-arg name="name" value = "Jonh"/>
        <constructor-arg name="age" value = "30"/>
    </bean>
    <bean class="com.test.entity.Staff">
        <constructor-arg name="name" value = "Jam"/>
        <constructor-arg name="age" value = "21"/>
    </bean>
  </list>
</property>

Solution 12 - Java

Use list-class attribute in util:list to make a standalone list of any particular type. for example if you want to make list of type ArrayList:

<util:list id="namesList" list-class="java.util.ArrayList" value-type="java.lang.String">
  <value>Abhay</value>
  <value>ankit</value>
  <value>Akshansh</value>
  <value>Db</value>
</util:list>

or if you want to make a list of type LinkedList then :

<util:list id="namesList" list-class="java.util.LinkedList" value-type="java.lang.String">
  <value>Abhay</value>
  <value>ankit</value>
  <value>Akshansh</value>
  <value>Db</value>
</util:list>

Solution 13 - Java

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionguerdaView Question on Stackoverflow
Solution 1 - JavasimonlordView Answer on Stackoverflow
Solution 2 - JavastackerView Answer on Stackoverflow
Solution 3 - JavaKoray TugayView Answer on Stackoverflow
Solution 4 - JavaJakub KubrynskiView Answer on Stackoverflow
Solution 5 - JavahajuView Answer on Stackoverflow
Solution 6 - JavaStephen CView Answer on Stackoverflow
Solution 7 - JavaRaM PrabUView Answer on Stackoverflow
Solution 8 - JavaHari KrishnaView Answer on Stackoverflow
Solution 9 - JavaJuan PerezView Answer on Stackoverflow
Solution 10 - JavaJose AlbanView Answer on Stackoverflow
Solution 11 - JavadqtheView Answer on Stackoverflow
Solution 12 - JavaAkshansh SaxenaView Answer on Stackoverflow
Solution 13 - JavaSlava BabinView Answer on Stackoverflow