web-dev-qa-db-fra.com

Comment définir un bean List au printemps?

J'utilise Spring pour définir les étapes de mon application. Il est configuré pour que la classe nécessaire (appelée ici Configurator) soit injectée avec les étapes.
Maintenant, j'ai besoin de la liste des étapes d'une autre classe, nommée LoginBean. La Configurator ne donne pas accès à sa liste d'étapes.

Je ne peux pas changer de classe Configurator.

Mon idée:
Définissez un nouveau haricot appelé Stages et injectez-le dans Configurator et LoginBean. Le problème avec cette idée est que je ne sais pas comment transformer cette propriété:

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

dans un haricot.

Quelque chose comme ça ne marche pas:

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

Quelqu'un peut-il m'aider avec ça?

192
guerda

Importez l'espace de noms spring util. Ensuite, vous pouvez définir un bean de liste comme suit:

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

Le type-valeur est le type générique à utiliser et est facultatif. Vous pouvez également spécifier la classe d'implémentation de la liste à l'aide de l'attribut list-class.

272
simonlord

Voici une méthode:

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

Une autre option consiste à utiliser JavaConfig. En supposant que toutes les étapes soient déjà enregistrées en tant que haricots de printemps, il vous suffit de:

@Autowired
private List<Stage> stages;

et spring les injectera automatiquement dans cette liste. Si vous devez préserver l'ordre (la solution supérieure ne le fait pas), vous pouvez le faire comme suit:

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

  @Autowired
  private Stage2 stage2;

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

L’autre solution pour préserver l’ordre consiste à utiliser une annotation @Order sur les haricots. Ensuite, la liste contiendra les haricots ordonnés par valeur d'annotation croissante.

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

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

Et dans SomeClass:

class SomeClass {

    private List<TypeForList> myList;

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

}
30
Koray Tugay

Stacker a posé une excellente réponse. Je ferais un pas de plus pour le rendre plus dynamique et utiliserais Spring 3 EL Expression.

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

J'essayais de comprendre comment je pouvais faire cela avec la liste util: mais je ne pouvais pas le faire fonctionner à cause d'erreurs de conversion.

8
haju

Je pense que vous recherchez peut-être org.springframework.beans.factory.config.ListFactoryBean .

Vous déclarez une instance ListFactoryBean, en fournissant la liste à instancier en tant que propriété avec un élément _<list>_ comme valeur, et attribuez au bean un attribut id. Ensuite, chaque fois que vous utilisez le id déclaré en tant que ref ou similaire dans une autre déclaration de bean, une nouvelle copie de la liste est instanciée. Vous pouvez également spécifier la classe List à utiliser.

4
Stephen C

Vous venez de supprimer id des haricots à l'intérieur de la balise <list>. Comme ça:

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

Utilisez l’espace de noms util, vous pourrez enregistrer la liste en tant que bean dans le contexte de votre application. Vous pouvez ensuite réutiliser la liste pour l'injecter dans d'autres définitions de bean.

1
Juan Perez

En complément de la réponse de Jakub, si vous envisagez d’utiliser JavaConfig, vous pouvez également procéder au câblage automatique de cette façon:

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

définir ces haricots (test1, test2) après :)

1
RaM PrabU

Et voici comment injecter un ensemble dans une propriété au printemps:

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