Como definir um bean de lista no Spring?

203

Estou usando o Spring para definir estágios no meu aplicativo. Está configurado que a classe necessária (aqui chamada Configurator) é injetada com os estágios.
Agora eu preciso da Lista de estágios em outra classe, chamadaLoginBean . O Configuratornão oferece acesso à sua lista de estágios.

Eu não posso mudar de classe Configurator.

Minha idéia:
defina um novo bean chamado Stages e injete-o no Configuratore LoginBean. Meu problema com essa idéia é que não sei como transformar essa propriedade:

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

em um feijão.

Algo assim não funciona:

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

Alguém pode me ajudar com isso?

guerda
fonte

Respostas:

279

Importe o espaço para nome do utilitário Spring. Então você pode definir um bean de lista da seguinte maneira:

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

O tipo de valor é o tipo de genéricos a ser usado e é opcional. Você também pode especificar a classe de implementação lista usando o atributo list-class.

simonlord
fonte
10
e, obviamente, o conteúdo da lista pode ser valores, referências e feijão etc ..
simonlord
Resposta maravilhosa, é mais "spring-like"
jpaoletti
1
simples:<property name="beanList" ref="myList"/>
Manuel Spigolon 17/03/2014
1
Olá, estou recebendo este cvc-complex-type.2.4.c: O caractere curinga correspondente é rigoroso, mas nenhuma declaração pode ser encontrada para o elemento 'value'. I h av namespace adicionado e schemaLocation ainda
Vishal
17
Acabei de perceber que @Autwiredisso não ajuda ao injetar uma lista criada dessa maneira. No entanto, @Resourcefunciona. ie@Resource List<String> myList
Matt Friedman
173

Aqui está um 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>
empilhador
fonte
1
+1 - Eu não sabia que você poderia fazer isso (embora eu possa ver que deve funcionar). Sugestão: acho que você deve poder incorporar as StageClassdeclarações do bean para <list>evitar a necessidade dos <ref>elementos.
Stephen C
9
você também pode usar util: lista para dar-lhe um ArrayList
Richard
É possível incorporar essas definições de bean em "<list> </list>"?
Sefler
@Sefler sim, as definições devem ser idênticos lá
eis
Existe uma armadilha: se você estiver usando @Autowired, verifique se o seu pojo também é do tipo "ArrayList" e não apenas "List", ou você pode obter algo completamente diferente.
Tilman Hausherr
38

Outra opção é usar o JavaConfig. Supondo que todas as etapas já estejam registradas como beans primavera, você apenas precisa:

@Autowired
private List<Stage> stages;

e a primavera os injetará automaticamente nesta lista. Se você precisar preservar a ordem (a solução superior não faz isso), é possível fazer da seguinte maneira:

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

  @Autowired
  private Stage2 stage2;

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

A outra solução para preservar a ordem é usar uma @Orderanotação nos beans. A lista conterá beans ordenados pelo valor da anotação crescente.

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

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

E em SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Koray Tugay
fonte
8

O Stacker ofereceu uma ótima resposta. Eu daria um passo adiante para torná-lo mais dinâmico e usar o Spring 3 EL Expression.

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

Eu estava tentando descobrir como eu poderia fazer isso com o util: list, mas não consegui fazê-lo funcionar devido a erros de conversão.

haju
fonte
4

Eu acho que você pode estar procurando org.springframework.beans.factory.config.ListFactoryBean.

Você declara uma instância ListFactoryBean, fornecendo a lista a ser instanciada como uma propriedade com um <list>elemento como seu valor e idatribui um atributo ao bean . Então, cada vez que você usa o declarado idcomo refou similar em alguma outra declaração de bean, uma nova cópia da lista é instanciada. Você também pode especificar a Listclasse a ser usada.

Stephen C
fonte
É uma boa dica, mas não consigo funcionar. a resposta de stakker funcionou. +1 para a dica.
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>  

defina esses beans (test1, test2) depois :)

RaM PrabU
fonte
1

Use o namespace util, você poderá registrar a lista como um bean em seu contexto de aplicativo. Você pode reutilizar a lista para injetá-la em outras definições de bean.

Juan Perez
fonte
1

Como complemento à resposta de Jakub, se você planeja usar o JavaConfig, também é possível conectar automaticamente dessa maneira:

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

Você acabou de remover ida <list>tag dentro dos grãos . Como isso:

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

E é assim que injetar o conjunto em alguma propriedade no 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
fonte
0

Injetar lista de strings.

Suponha que você tenha uma classe de modelo de países que faça uma lista de cadeias de caracteres como abaixo.

public class Countries {
    private List<String> countries;

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

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

}

Após a definição xml, defina um bean e injete uma 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>

Link de referência

Injetar lista de Pojos

Suponha que você tenha uma classe de modelo como abaixo.

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

}

Definições de Bean.

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

Link de referência .

Hari Krishna
fonte