¿Cómo definir un bean de lista en primavera?

203

Estoy usando Spring para definir etapas en mi aplicación. Está configurado para que la clase necesaria (aquí llamada Configurator) se inyecte con las etapas.
Ahora necesito la Lista de etapas en otra clase, llamada LoginBean. El Configuratorno ofrece acceso a su Lista de etapas.

No puedo cambiar la clase Configurator.

Mi idea:
definir un nuevo bean llamado Etapas e inyectarlo en Configuratory LoginBean. Mi problema con esta idea es que no sé cómo transformar esta propiedad:

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

en un frijol

Algo como esto no funciona:

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

¿Puede alguien ayudarme con esto?

guerda
fuente

Respuestas:

279

Importe el espacio de nombres Spring Util. Luego puede definir un bean de lista de la siguiente manera:

<?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>

El tipo de valor es el tipo genérico que se utilizará y es opcional. También puede especificar la clase de lista de aplicación con el atributo list-class.

simonlord
fuente
10
y obviamente el contenido de la lista puede ser valores, referencias y beans, etc.
simonlord
Maravillosa respuesta, es más "primaveral"
jpaoletti
1
simple:<property name="beanList" ref="myList"/>
Manuel Spigolon
1
Hola, estoy obteniendo este cvc-complex-type.2.4.c: el comodín coincidente es estricto, pero no se puede encontrar ninguna declaración para el elemento 'valor'. He agregado un espacio de nombres y un esquema de ubicación todavía
visual
17
Acabo de notar que eso @Autwiredno ayuda al inyectar una lista creada de esta manera. Sin embargo, @Resourcefunciona. es decir@Resource List<String> myList
Matt Friedman
173

Aquí hay un método:

<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>
apilador
fuente
1
+1 - No sabía que podías hacer eso (aunque puedo ver que debería funcionar). Sugerencia: Creo que debería poder incrustar las StageClassdeclaraciones de frijol para <list>evitar la necesidad de los <ref>elementos.
Stephen C
9
también podría usar util: list para darle una lista de arrays
Richard
¿Es posible incrustar esas definiciones de frijol en "<list> </list>"?
Sefler
@Sefler sí, las definiciones deben ser idénticos no
EIS
Hay una trampa: si usa @Autowired, asegúrese de que su pojo también sea del tipo "ArrayList" y no solo "List" o podría obtener algo completamente diferente.
Tilman Hausherr
38

Otra opción es usar JavaConfig. Suponiendo que todas las etapas ya están registradas como frijoles de primavera, solo tiene que:

@Autowired
private List<Stage> stages;

y spring los inyectará automáticamente en esta lista. Si necesita preservar el orden (la solución superior no lo hace), puede hacerlo de esa manera:

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

  @Autowired
  private Stage2 stage2;

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

La otra solución para preservar el orden es usar una @Orderanotación en beans. Luego, la lista contendrá beans ordenados por valor de anotación ascendente.

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

@Bean
@Order(2)
public Stage stage2() {
    return new Stage2();
}
Jakub Kubrynski
fuente
34
<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>

Y en SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Koray Tugay
fuente
8

Stacker planteó una gran respuesta, iría un paso más allá para hacerlo más dinámico y usar Spring 3 EL Expression.

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

Estaba tratando de descubrir cómo podría hacer esto con la lista util: pero no pude hacerlo funcionar debido a errores de conversión.

haju
fuente
4

Creo que puedes estar buscando org.springframework.beans.factory.config.ListFactoryBean.

Usted declara una instancia ListFactoryBean, proporcionando la lista para ser instanciada como una propiedad con un <list>elemento como su valor, y le da al bean un idatributo. Luego, cada vez que use el declarado idcomo refo similar en alguna otra declaración de bean, se crea una nueva copia de la lista. También puede especificar la Listclase que se utilizará.

Stephen C
fuente
Es una buena pista, pero no lo hago funcionar. La respuesta de Stakker funcionó. +1 para la pista.
guerda
2
 <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 esos beans (test1, test2) después :)

RaM PrabU
fuente
1

Utilice el espacio de nombres de utilidades, podrá registrar la lista como un bean en el contexto de su aplicación. Luego puede reutilizar la lista para inyectarla en otras definiciones de bean.

Juan perez
fuente
1

Como complemento a la respuesta de Jakub, si planea usar JavaConfig, también puede conectar automáticamente de esa manera:

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);
    }
}
Jose Alban
fuente
1

Simplemente eliminas idlos frijoles dentro de la <list>etiqueta. Me gusta esto:

<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>
dqthe
fuente
0

Y así es como inyectar set en alguna propiedad en 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>
Slava Babin
fuente
0

Inyectar lista de cadenas.

Suponga que tiene una clase de modelo de países que toma una lista de cadenas como la siguiente.

public class Countries {
    private List<String> countries;

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

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

}

Siguiendo la definición xml, defina un bean e inyecte una lista de países.

<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>

Enlace de referencia

Inyectar lista de Pojos

Supongamos que tiene una clase de modelo como la siguiente.

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

}

Frijoles Definiciones.

 <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>

Enlace de referencia .

Hari Krishna
fuente