Как определить бин List весной?

203

Я использую Spring для определения этапов в моем приложении. Настраивается, что необходимый класс (здесь называется Configurator) вводится с этапами.
Теперь мне нужен список этапов в другом классе с именем LoginBean. ConfiguratorНе предоставляет доступ к своему списку этапов.

Я не могу изменить класс Configurator.

Моя идея:
определить новый бин с именем Stages и добавить его в Configuratorи LoginBean. Моя проблема с этой идеей состоит в том, что я не знаю, как преобразовать это свойство:

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

в боб.

Как то так не работает

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

Кто-нибудь может мне помочь с этим?

guerda
источник

Ответы:

279

Импортируйте пространство имен spring util. Затем вы можете определить bean-компонент списка следующим образом:

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

Тип-значения - это общий тип, который будет использоваться, и является необязательным. Вы также можете указать класс реализации списка, используя атрибут list-class.

simonlord
источник
10
и, очевидно, содержимое списка может быть значениями, ссылками,
бинами
Чудесный ответ, он более "весенний"
jpaoletti
1
просто:<property name="beanList" ref="myList"/>
Мануэль Спиголон
1
Привет, я получаю этот cvc-complex-type.2.4.c: соответствующий шаблон является строгим, но не может быть найдено объявление для элемента 'value'. Я еще добавил пространство имен и
схему
17
Я только заметил, что @Autwiredэто не помогает при добавлении списка, созданного таким образом. Однако @Resourceработает. то есть@Resource List<String> myList
Мэтт Фридман
173

Вот один из методов:

<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 - я не знал, что ты мог бы сделать это (хотя я вижу, что это должно работать). Предложение: я думаю, что вы должны иметь возможность встраивать StageClassдекларации bean во <list>избежание необходимости в <ref>элементах.
Стивен С
9
Вы также можете использовать util: list, чтобы получить массив
Ричард
Можно ли вставить эти определения bean-компонентов в «<list> </ list>»?
Сефлер
@Sefler да, определения должны быть идентичны там
eis
Подводный камень: при использовании @Autowired убедитесь, что ваш pojo также имеет тип «ArrayList», а не просто «List», иначе вы можете получить что-то совершенно другое.
Тилман
38

Другой вариант - использовать JavaConfig. Предполагая, что все стадии уже зарегистрированы как бобы весны, вам просто нужно:

@Autowired
private List<Stage> stages;

и весна автоматически добавит их в этот список. Если вам нужно сохранить порядок (верхнее решение этого не делает), вы можете сделать это следующим образом:

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

  @Autowired
  private Stage2 stage2;

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

Другое решение для сохранения порядка - использование @Orderаннотации на бобах. Тогда список будет содержать компоненты, упорядоченные по возрастанию значения аннотации.

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

И в SomeClass:

class SomeClass {

    List<TypeForList> myList;

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

}
Корай Тугай
источник
8

Stacker дал отличный ответ, я бы пошел еще дальше, чтобы сделать его более динамичным и использовать Spring 3 EL Expression.

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

Я пытался выяснить, как я могу сделать это с помощью util: list, но не смог заставить его работать из-за ошибок преобразования.

Haju
источник
4

Я думаю, что вы можете искать org.springframework.beans.factory.config.ListFactoryBean.

Вы объявляете экземпляр ListFactoryBean, предоставляя список для создания экземпляра как свойство с <list>элементом в качестве его значения, и даете bean-компоненту idатрибут. Затем каждый раз, когда вы используете объявленный idкак refили подобное в каком-либо другом объявлении bean-компонента, создается новая копия списка. Вы также можете указать Listкласс, который будет использоваться.

Стивен С
источник
Это хороший намек, но я не понимаю, как это работает. ответ стаккера сработал. +1 за подсказку.
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>  

определите эти бины (test1, test2) впоследствии :)

Рам ПрабУ
источник
1

Используйте пространство имен util, вы сможете зарегистрировать список как компонент в контексте вашего приложения. Затем вы можете повторно использовать список, чтобы добавить его в другие определения bean-компонентов.

Хуан Перес
источник
1

В дополнение к ответу Якуба, если вы планируете использовать JavaConfig, вы также можете выполнить автоматическое подключение следующим образом:

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

Вы просто удаляете idиз бобов внутри <list>тега. Как это:

<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
источник
0

И вот как вставить множество в какое-то свойство в 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>
Слава Бабин
источник
0

Вставить список строк.

Предположим, у вас есть класс моделей стран, который принимает список строк, как показано ниже.

public class Countries {
    private List<String> countries;

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

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

}

Следующее определение xml определяет бин и вводит список стран.

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

Ссылка ссылка

Вставить список Pojos

Предположим, у вас есть модель класса, как показано ниже.

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

}

Определения Бина.

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

Ссылка Ссылка .

Хари Кришна
источник