Come definire un bean di lista in primavera?


203

Sto usando Spring per definire le fasi della mia applicazione. È configurato per Configuratoriniettare la classe necessaria (qui chiamata ) con gli stage.
Ora ho bisogno dell'elenco delle fasi in un'altra classe, chiamato LoginBean. The Configuratornon offre accesso al suo Elenco di fasi.

Non posso cambiare la classe Configurator .

La mia idea:
definire un nuovo bean chiamato Stages e iniettarlo in Configuratore LoginBean. Il mio problema con questa idea è che non so come trasformare questa proprietà:

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

in un fagiolo.

Qualcosa del genere non funziona:

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

Qualcuno può aiutarmi con questo?

Risposte:


279

Importa lo spazio dei nomi util della primavera. Quindi è possibile definire un bean di elenco come segue:

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

Il valore-tipo è il tipo generico da utilizzare ed è facoltativo. È inoltre possibile specificare la classe di implementazione dell'elenco utilizzando l'attributo list-class.


10
e ovviamente i contenuti dell'elenco possono essere valori, riferimenti e bean ecc.
simonlord

Risposta meravigliosa, è più "primaverile"
jpaoletti,

1
semplice:<property name="beanList" ref="myList"/>
Manuel Spigolon

1
Ciao, sto ottenendo questo cvc-complex-type.2.4.c: il carattere jolly corrispondente è rigoroso, ma non è possibile trovare alcuna dichiarazione per l'elemento 'valore'. Ho h ave namespace aggiunto e schemaLocation ancora
Vishal

17
Ho appena notato che @Autwirednon aiuta quando si inietta un elenco creato in questo modo. Tuttavia, @Resourcefunziona. vale a dire@Resource List<String> myList
Matt Friedman,

173

Ecco un metodo:

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

1
+1 - Non sapevo che potessi farlo (anche se vedo che dovrebbe funzionare). Suggerimento: penso che dovresti essere in grado di incorporare le StageClassdichiarazioni del bean per <list>evitare la necessità degli <ref>elementi.
Stephen C

9
potresti anche usare util: list per darti un arraylist
Richard

È possibile incorporare tali definizioni di bean in "<list> </list>"?
Sefler,

@Sefler sì, le definizioni dovrebbero essere identiche lì
eis

C'è una trappola: se usi @Autowired, assicurati che il tuo pojo sia anche di tipo "ArrayList" e non solo "List" o potresti ottenere qualcosa di completamente diverso.
Tilman Hausherr,

38

Un'altra opzione è utilizzare JavaConfig. Supponendo che tutte le fasi siano già registrate come fagiolini, non ti resta che:

@Autowired
private List<Stage> stages;

e la primavera li inietterà automaticamente in questo elenco. Se devi conservare l'ordine (la soluzione superiore non lo fa) puoi farlo in questo modo:

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

  @Autowired
  private Stage2 stage2;

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

L'altra soluzione per preservare l'ordine è usare @Orderun'annotazione sui bean. Quindi l'elenco conterrà i bean ordinati per valore di annotazione crescente.

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

@Bean
@Order(2)
public Stage stage2() {
    return new Stage2();
}

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 in SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}

8

Stacker ha dato un'ottima risposta, farei un passo avanti per renderlo più dinamico e utilizzare Spring 3 EL Expression.

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

Stavo cercando di capire come avrei potuto farlo con util: list ma non riuscivo a farlo funzionare a causa di errori di conversione.


4

Penso che potresti essere alla ricerca org.springframework.beans.factory.config.ListFactoryBean.

Dichiarare un'istanza ListFactoryBean, fornendo l'elenco da istanziare come proprietà con un <list>elemento come valore e assegnare al bean un idattributo. Quindi, ogni volta che si utilizza dichiarato idcome refo simile in un'altra dichiarazione bean, viene istanziata una nuova copia dell'elenco. Puoi anche specificare la Listclasse da usare.


È un bel suggerimento, ma non riesco a farlo funzionare. la risposta di Stakker ha funzionato. +1 per il suggerimento.
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>  

definire quei bean (test1, test2) in seguito :)


1

Utilizza lo spazio dei nomi util, sarai in grado di registrare l'elenco come bean nel contesto dell'applicazione. È quindi possibile riutilizzare l'elenco per iniettarlo in altre definizioni di bean.


1

In aggiunta alla risposta di Jakub, se prevedi di utilizzare JavaConfig, puoi anche eseguire l'autowire in questo modo:

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

1

Basta rimuovere idi fagioli dal <list>tag. Come questo:

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

0

E questo è come iniettare set in alcune proprietà in primavera:

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

0

Inietta l'elenco di stringhe.

Supponiamo di avere una classe di modello Paesi che prende l'elenco di stringhe come di seguito.

public class Countries {
    private List<String> countries;

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

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

}

La seguente definizione XML definisce un bean e inietta un elenco di paesi.

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

Inietta l'elenco di Pojos

Supponiamo che tu abbia una classe di modello come di seguito.

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

}

Definizioni dei fagioli.

 <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 di riferimento .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.