Wie definiere ich eine List Bean im Frühjahr?

203

Ich verwende Spring, um Phasen in meiner Anwendung zu definieren. Es ist konfiguriert, dass der erforderlichen Klasse (hier genannt Configurator) die Stufen injiziert werden.
Jetzt brauche ich die Liste der Stufen in einer anderen Klasse mit dem Namen LoginBean. Der Configuratorbietet keinen Zugang zu seiner Liste der Stufen.

Ich kann die Klasse nicht ändern Configurator.

Meine Idee:
Definieren Sie eine neue Bohne namens Stages und injizieren Sie sie in Configuratorund LoginBean. Mein Problem mit dieser Idee ist, dass ich nicht weiß, wie ich diese Eigenschaft transformieren soll:

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

in eine Bohne.

So etwas funktioniert nicht:

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

Kann mir jemand dabei helfen?

Guerda
quelle

Antworten:

279

Importieren Sie den Spring Util-Namespace. Anschließend können Sie eine List Bean wie folgt definieren:

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

Der Werttyp ist der zu verwendende generische Typ und optional. Sie können die Listenimplementierungsklasse auch mithilfe des Attributs angeben list-class.

Simonlord
quelle
10
und offensichtlich kann der Inhalt der Liste Werte, Referenzen und Bohnen usw. sein
Simonlord
Wunderbare Antwort, es ist eher "frühlingshaft"
jpaoletti
1
einfach:<property name="beanList" ref="myList"/>
Manuel Spigolon
1
Hallo, ich erhalte diesen cvc-complex-type.2.4.c: Der übereinstimmende Platzhalter ist streng, aber für das Element 'value' kann keine Deklaration gefunden werden. Ich habe noch Namespace und SchemaLocation hinzugefügt
vishal
17
Mir ist gerade aufgefallen, dass @Autwireddies beim Einfügen einer auf diese Weise erstellten Liste nicht hilft. Funktioniert jedoch @Resource. dh@Resource List<String> myList
Matt Friedman
173

Hier ist eine Methode:

<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>
Stapler
quelle
1
+1 - Ich wusste nicht, dass du das kannst (obwohl ich sehe, dass es funktionieren sollte). Vorschlag: Ich denke, Sie sollten in der Lage sein, die StageClassBean-Deklarationen einzubetten, <list>um die Notwendigkeit der <ref>Elemente zu vermeiden .
Stephen C
9
Sie können auch util: list verwenden, um Ihnen eine Arrayliste zu geben
Richard
Ist es möglich, diese Bean-Definitionen in "<list> </ list>" einzubetten?
Sefler
@Sefler ja, die Definitionen sollten dort identisch sein
eis
Es gibt eine Gefahr: Wenn Sie @Autowired verwenden, stellen Sie sicher, dass Ihr Pojo auch vom Typ "ArrayList" und nicht nur "List" ist, da Sie sonst möglicherweise etwas völlig anderes erhalten.
Tilman Hausherr
38

Eine weitere Option ist die Verwendung von JavaConfig. Angenommen, alle Stufen sind bereits als Frühlingsbohnen registriert, müssen Sie nur:

@Autowired
private List<Stage> stages;

und spring fügt sie automatisch in diese Liste ein. Wenn Sie die Ordnung bewahren müssen (die obere Lösung tut das nicht), können Sie dies folgendermaßen tun:

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

  @Autowired
  private Stage2 stage2;

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

Die andere Lösung zur Aufrechterhaltung der Ordnung ist die Verwendung einer @OrderAnmerkung zu Bohnen. Die Liste enthält dann Beans, die nach aufsteigendem Anmerkungswert sortiert sind.

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

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

Und in SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Koray Tugay
quelle
8

Stacker gab eine großartige Antwort, ich würde einen Schritt weiter gehen, um es dynamischer zu machen und Spring 3 EL Expression zu verwenden.

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

Ich habe versucht herauszufinden, wie ich dies mit der util: list tun kann, konnte es aber aufgrund von Konvertierungsfehlern nicht zum Laufen bringen.

haju
quelle
4

Ich denke, Sie suchen vielleicht org.springframework.beans.factory.config.ListFactoryBean.

Sie deklarieren eine ListFactoryBean-Instanz, geben die zu instanziierende Liste als Eigenschaft mit einem <list>Element als Wert an und geben der Bean ein idAttribut. Jedes Mal, wenn Sie die deklarierte idals refoder ähnlich in einer anderen Bean-Deklaration verwenden, wird eine neue Kopie der Liste instanziiert. Sie können auch die Listzu verwendende Klasse angeben .

Stephen C.
quelle
Es ist ein netter Hinweis, aber ich verstehe es nicht. Stakkers Antwort funktionierte. +1 für den Hinweis.
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>  

Definiere diese Beans (test1, test2) danach :)

RaM PrabU
quelle
1

Verwenden Sie den util-Namespace, um die Liste als Bean in Ihrem Anwendungskontext zu registrieren. Sie können die Liste dann wiederverwenden, um sie in andere Bean-Definitionen einzufügen.

Juan Perez
quelle
1

Als Ergänzung zu Jakubs Antwort können Sie, wenn Sie JavaConfig verwenden möchten, auch auf diese Weise automatisch verdrahten:

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

Sie entfernen idnur aus Bohnen innerhalb des <list>Tags. So was:

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

Und so injizieren Sie Set in eine Eigenschaft im Frühjahr:

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

Injizieren Sie eine Liste von Zeichenfolgen.

Angenommen, Sie haben eine Modellklasse für Länder, die eine Liste von Zeichenfolgen wie unten enthält.

public class Countries {
    private List<String> countries;

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

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

}

Nach der XML-Definition definieren Sie eine Bean- und Inject-Liste der Länder.

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

Referenz - Link

Injizieren Sie die Liste der Pojos

Angenommen, Sie haben eine Modellklasse wie unten.

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

}

Bohnendefinitionen.

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

Referenz Verbindung .

Hari Krishna
quelle