Bagaimana cara mendefinisikan kacang Daftar di Musim Semi?

203

Saya menggunakan Spring untuk menentukan tahapan dalam aplikasi saya. Ini dikonfigurasi bahwa kelas yang diperlukan (di sini disebut Configurator) disuntikkan dengan tahapan.
Sekarang saya perlu Daftar Tahapan di kelas lain, bernama LoginBean. The Configuratortidak menawarkan akses ke Daftar Tahapannya.

Saya tidak bisa mengubah kelas Configurator.

Ide Saya:
Tentukan kacang baru yang disebut Tahapan dan suntikkan ke Configuratordan LoginBean. Masalah saya dengan ide ini adalah saya tidak tahu bagaimana mengubah properti ini:

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

menjadi kacang.

Sesuatu seperti ini tidak berfungsi:

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

Adakah yang bisa membantu saya dengan ini?

guerda
sumber

Jawaban:

279

Impor pegas menggunakan namespace. Kemudian Anda dapat mendefinisikan kacang daftar sebagai berikut:

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

Tipe nilai adalah tipe generik yang akan digunakan, dan bersifat opsional. Anda juga dapat menentukan kelas implementasi daftar menggunakan atribut list-class.

simonlord
sumber
10
dan jelas isi dari daftar bisa berupa nilai, referensi, dan kacang-kacangan dll.
simonlord
Jawaban yang bagus, ini lebih "seperti musim semi"
jpaoletti
1
sederhana:<property name="beanList" ref="myList"/>
Manuel Spigolon
1
Hai Saya mendapatkan cvc-complex-type.2.4.c: Wildcard yang cocok ini ketat, tetapi tidak ada deklarasi yang dapat ditemukan untuk elemen 'value'. Saya sudah menambahkan namespace dan schemaLocation
vishal
17
Saya hanya memperhatikan bahwa @Autwiredtidak membantu ketika menyuntikkan daftar yang dibuat dengan cara ini. Namun, @Resourceberhasil. yaitu@Resource List<String> myList
Matt Friedman
173

Berikut ini satu metode:

<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>
stacker
sumber
1
+1 - Saya tidak tahu Anda bisa melakukan itu (meskipun saya bisa melihat itu seharusnya berfungsi). Saran: Saya pikir Anda harus dapat menanamkan StageClassdeklarasi kacang dalam <list>menghindari kebutuhan akan <ref>elemen.
Stephen C
9
Anda juga bisa menggunakan util: daftar untuk memberi Anda daftar-array
Richard
Apakah mungkin untuk menanamkan definisi kacang itu ke "<list> </list>"?
Sefler
@ Penyair ya, definisi harus identik di sana
eis
Ada jebakan: jika menggunakan @Autowired, pastikan bahwa pojo Anda juga bertipe "ArrayList" dan bukan hanya "Daftar" atau Anda bisa mendapatkan sesuatu yang sama sekali berbeda.
Tilman Hausherr
38

Pilihan lain adalah menggunakan JavaConfig. Dengan asumsi bahwa semua tahap sudah terdaftar sebagai kacang hijau, Anda hanya perlu:

@Autowired
private List<Stage> stages;

dan pegas akan secara otomatis memasukkannya ke dalam daftar ini. Jika Anda perlu mempertahankan pesanan (solusi teratas tidak melakukan itu), Anda dapat melakukannya dengan cara itu:

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

  @Autowired
  private Stage2 stage2;

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

Solusi lain untuk menjaga ketertiban adalah menggunakan @Orderanotasi pada kacang. Kemudian daftar akan berisi kacang yang dipesan dengan nilai penjelasan naik.

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

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

Dan di SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Koray Tugay
sumber
8

Stacker mengajukan jawaban yang bagus, saya akan melangkah lebih jauh untuk membuatnya lebih dinamis dan menggunakan Spring 3 EL Expression.

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

Saya mencoba mencari tahu bagaimana saya bisa melakukan ini dengan daftar util: tapi tidak bisa berfungsi karena kesalahan konversi.

haju
sumber
4

Saya pikir Anda mungkin mencari org.springframework.beans.factory.config.ListFactoryBean.

Anda mendeklarasikan instance ListFactoryBean, memberikan daftar untuk dipakai sebagai properti dengan <list>elemen sebagai nilainya, dan memberikan kacang idatribut. Kemudian, setiap kali Anda menggunakan yang dinyatakan idsebagai refatau serupa di beberapa pernyataan kacang lainnya, salinan baru dari daftar akan dipakai. Anda juga dapat menentukan Listkelas yang akan digunakan.

Stephen C
sumber
Ini petunjuk yang bagus, tapi saya tidak membuatnya bekerja. Jawaban Stakker berhasil. +1 untuk petunjuknya.
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>  

tentukan kacang itu (test1, test2) sesudahnya :)

RaM PrabU
sumber
1

Gunakan namespace util, Anda akan dapat mendaftarkan daftar sebagai kacang dalam konteks aplikasi Anda. Anda kemudian dapat menggunakan kembali daftar untuk menyuntikkannya dalam definisi kacang lainnya.

Juan Perez
sumber
1

Sebagai tambahan untuk jawaban Jakub, jika Anda berencana untuk menggunakan JavaConfig, Anda juga dapat autowire seperti itu:

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

Anda cukup menghapus idkacang di dalam <list>tag. Seperti ini:

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

Dan ini adalah cara menyuntikkan set di beberapa properti di 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
sumber
0

Suntikkan daftar string.

Misalkan Anda memiliki kelas model Negara yang mengambil daftar string seperti di bawah ini.

public class Countries {
    private List<String> countries;

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

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

}

Mengikuti definisi xml, tentukan daftar negara yang disuntik dan disuntik.

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

Tautan referensi

Suntikkan daftar Pojo

Misalkan jika Anda memiliki kelas model seperti di bawah ini.

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

}

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

Tautan Referensi .

Hari Krishna
sumber