Jak zdefiniować ziarno listy na wiosnę?

203

Używam Springa do definiowania etapów w mojej aplikacji. Jest skonfigurowane, że niezbędna klasa (tutaj nazywana Configurator) jest wstrzykiwana z etapami.
Teraz potrzebuję Listy Etapów w innej klasie, o nazwie LoginBean. ConfiguratorNie oferuje dostęp do swojej listy etapach.

Nie mogę zmienić klasy Configurator.

Mój pomysł:
zdefiniuj nową fasolę o nazwie Etapy i wstrzyknij ją do Configuratori LoginBean. Mój problem z tym pomysłem polega na tym, że nie wiem, jak przekształcić tę właściwość:

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

w fasolę.

Coś takiego nie działa:

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

Czy ktoś może mi w tym pomóc?

guerda
źródło

Odpowiedzi:

279

Zaimportuj przestrzeń nazw wiosn. Następnie możesz zdefiniować komponent bean w następujący sposób:

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

Typ wartości jest typem ogólnym, który ma być używany, i jest opcjonalny. Możesz także określić klasę implementacji listy, używając atrybutu list-class.

simonlord
źródło
10
i oczywiście zawartość listy może być wartościami, referencjami,
fasolami
Cudowna odpowiedź, bardziej „wiosenna”
jpaoletti
1
proste:<property name="beanList" ref="myList"/>
Manuel Spigolon
1
Cześć. Otrzymuję ten cvc-complex-type.2.4.c: Pasujący znak wieloznaczny jest ścisły, ale nie można znaleźć deklaracji dla elementu „wartość”. Dodałem jeszcze przestrzeń nazw i schemat Lokalizacja
vishal
17
Właśnie zauważyłem, że @Autwiredto nie pomaga, gdy wstrzykuje się listę utworzoną w ten sposób. Jednak @Resourcedziała. tj.@Resource List<String> myList
Matt Friedman
173

Oto jedna metoda:

<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>
układacz
źródło
1
+1 - nie wiedziałem, że możesz to zrobić (choć widzę, że to powinno działać). Sugestia: Myślę, że powinieneś być w stanie osadzić StageClassdeklaracje fasoli w celu <list>uniknięcia potrzeby <ref>elementów.
Stephen C
9
możesz także użyć util: list, aby dać ci arraylistę
Richard
Czy można osadzić te definicje fasoli w „<list> </list>”?
Sefler,
@Sefler tak, definicje powinny być identyczne tam
eis
Istnieje pułapka: jeśli używasz @Autowired, upewnij się, że twoje pojęcie jest również typu „ArrayList”, a nie tylko „List”, bo możesz dostać coś zupełnie innego.
Tilman Hausherr
38

Inną opcją jest użycie JavaConfig. Zakładając, że wszystkie etapy są już zarejestrowane jako fasolka szparagowa, wystarczy:

@Autowired
private List<Stage> stages;

a wiosna automatycznie doda je do tej listy. Jeśli chcesz zachować porządek (górne rozwiązanie tego nie robi), możesz to zrobić w następujący sposób:

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

  @Autowired
  private Stage2 stage2;

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

Innym rozwiązaniem dla zachowania porządku jest użycie @Orderadnotacji na fasoli. Następnie lista będzie zawierać fasole uporządkowane według rosnącej wartości adnotacji.

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

@Bean
@Order(2)
public Stage stage2() {
    return new Stage2();
}
Jakub Kubryński
źródło
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>

A w SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Koray Tugay
źródło
8

Stacker przedstawił świetną odpowiedź. Chciałbym pójść o krok dalej, aby uczynić go bardziej dynamicznym i zastosować wyrażenie Spring 3 EL Expression.

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

Próbowałem wymyślić, jak mogę to zrobić za pomocą funkcji util: list, ale nie mogłem go uruchomić z powodu błędów konwersji.

haju
źródło
4

Myślę, że możesz szukać org.springframework.beans.factory.config.ListFactoryBean.

Deklarujesz instancję ListFactoryBean, podając listę, która ma być tworzona jako właściwość z <list>elementem jako jej wartość, i nadajesz fasoli idatrybut. Następnie za każdym razem, gdy użyjesz deklarowanej idjako reflub podobnej w jakiejś innej deklaracji komponentu bean, tworzona jest nowa kopia listy. Możesz także określić Listklasę, która ma być używana.

Stephen C.
źródło
To miła wskazówka, ale nie działam. zadziałała odpowiedź Stakkera. +1 za podpowiedź.
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>  

następnie zdefiniuj te ziarna (test1, test2) :)

RaM PrabU
źródło
1

Korzystając z przestrzeni nazw util, będziesz mógł zarejestrować listę jako komponent bean w kontekście aplikacji. Następnie można ponownie użyć listy, aby wstrzyknąć ją do innych definicji komponentu bean.

Juan Perez
źródło
1

Jako dodatek do odpowiedzi Jakuba, jeśli planujesz używać JavaConfig, możesz również automatycznie uruchomić w ten sposób:

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
źródło
1

Po prostu usuwasz idz fasoli wewnątrz <list>tagu. Lubię to:

<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
źródło
0

Oto jak wstrzyknąć zestaw do jakiejś nieruchomości na wiosnę:

<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
źródło
0

Wstaw listę ciągów znaków.

Załóżmy, że masz klasę modelu Kraje, która przyjmuje listę ciągów jak poniżej.

public class Countries {
    private List<String> countries;

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

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

}

Zgodnie z definicją xml zdefiniuj listę fasoli i wstaw listę krajów.

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

Wstaw listę Pojos

Załóżmy, że masz klasę modelu jak poniżej.

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

}

Definicje fasoli.

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

Hari Krishna
źródło