如何在 Spring 中定义 List bean?

Posted

技术标签:

【中文标题】如何在 Spring 中定义 List bean?【英文标题】:How to define a List bean in Spring? 【发布时间】:2011-01-25 20:11:33 【问题描述】:

我正在使用 Spring 在我的应用程序中定义阶段。已配置为将必要的类(此处称为 Configurator)注入阶段。 现在我需要另一个类中的阶段列表,名为LoginBeanConfigurator 不提供访问他的阶段列表的权限。

我无法更改课程Configurator

我的想法: 定义一个名为 Stages 的新 bean 并将其注入 ConfiguratorLoginBean。 我对这个想法的问题是我不知道如何转换这个属性:

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

变成豆子。

这样的事情不起作用:

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

谁能帮我解决这个问题?

【问题讨论】:

【参考方案1】:

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

value-type 是要使用的泛型类型,是可选的。也可以使用list-class属性指定列表实现类。

【讨论】:

显然列表的内容可以是值、引用和bean等。 精彩的答案,更像是“弹簧” 简单:&lt;property name="beanList" ref="myList"/&gt; 您好,我收到了这个 cvc-complex-type.2.4.c:匹配的通配符是严格的,但找不到元素“值”的声明。我仍然添加了命名空间和 schemaLocation 我刚刚注意到@Autwired 在注入以这种方式创建的列表时没有帮助。但是,@Resource 有效。即@Resource List&lt;String&gt; myList【参考方案2】:

这是一种方法:

<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 - 我不知道你能做到这一点(尽管我可以看到它应该可以工作)。建议:我认为您应该能够在 &lt;list&gt; 中嵌入 StageClass bean 声明,从而避免需要 &lt;ref&gt; 元素。 你也可以使用 util:list 给你一个数组列表 是否可以将这些 bean 定义嵌入到“”中? @Sefler 是的,那里的定义应该是相同的 有一个陷阱:如果使用@Autowired,请确保您的 pojo 也是“ArrayList”类型,而不仅仅是“List”,否则您可能会得到完全不同的东西。【参考方案3】:

另一个选择是使用 JavaConfig。假设所有阶段都已注册为 spring bean,您只需:

@Autowired
private List<Stage> stages;

spring 会自动将它们注入到这个列表中。如果您需要保持顺序(上层解决方案不这样做),您可以这样做:

@Configuration
public class MyConfiguration 
  @Autowired
  private Stage1 stage1;

  @Autowired
  private Stage2 stage2;

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

另一种保持顺序的解决方案是在 bean 上使用 @Order 注释。然后列表将包含按注释值升序排列的bean。

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


@Bean
@Order(2)
public Stage stage2() 
    return new Stage2();

【讨论】:

【参考方案4】:
<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;
    


【讨论】:

【参考方案5】:

Stacker 提出了一个很好的答案,我会更进一步,使其更具动态性并使用 Spring 3 EL Expression。

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

我试图弄清楚如何使用 util:list 执行此操作,但由于转换错误而无法使其工作。

【讨论】:

这太棒了...使用“字典”Java 类而不是从字典中复制魔术字符串...谢谢!!【参考方案6】:

我想你可能正在寻找org.springframework.beans.factory.config.ListFactoryBean

您声明一个 ListFactoryBean 实例,提供要作为属性实例化的列表,并以 &lt;list&gt; 元素作为其值,并为 bean 提供 id 属性。然后,每次您将声明的id 用作ref 或其他一些bean 声明中的类似内容时,都会实例化一个新的列表副本。您还可以指定要使用的List 类。

【讨论】:

这是一个很好的提示,但我不明白。斯塔克的回答奏效了。 +1 提示。【参考方案7】:
 <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>  

之后定义那些 bean(test1,test2) :)

【讨论】:

【参考方案8】:

使用 util 命名空间,您将能够在应用程序上下文中将列表注册为 bean。然后,您可以重用该列表以将其注入到其他 bean 定义中。

【讨论】:

【参考方案9】:

作为对 Jakub 答案的补充,如果您打算使用 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);
    

【讨论】:

【参考方案10】:

您只需从 &lt;list&gt; 标记内的 bean 中删除 id。像这样:

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

【讨论】:

【参考方案11】:

注入字符串列表。

假设您有接受如下字符串列表的国家模型类。

public class Countries 
    private List<String> countries;

    public List<String> getCountries() 
        return countries;
       

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


按照 xml 定义定义一个 bean 并注入国家列表。

<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

注入 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 定义。

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

【讨论】:

【参考方案12】:

使用 util:list 中的 list-class 属性来制作任何特定类型的独立列表。例如,如果您想创建 ArrayList 类型的列表:

<util:list id="namesList" list-class="java.util.ArrayList" value-type="java.lang.String">
  <value>Abhay</value>
  <value>ankit</value>
  <value>Akshansh</value>
  <value>Db</value>
</util:list>

或者如果你想创建一个 LinkedList 类型的列表,那么:

<util:list id="namesList" list-class="java.util.LinkedList" value-type="java.lang.String">
  <value>Abhay</value>
  <value>ankit</value>
  <value>Akshansh</value>
  <value>Db</value>
</util:list>

【讨论】:

【参考方案13】:

这就是如何在 Spring 的某些属性中注入 set:

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

【讨论】:

以上是关于如何在 Spring 中定义 List bean?的主要内容,如果未能解决你的问题,请参考以下文章

spring bean重复定义不报错以及注入失败分析

如何调用spring配置文件手动注入的bean

spring工具类中注入使用bean

Spring各类集合注入

如何在自定义 Spring Security 登录成功处理程序中注入会话 bean

如何在 Spring Boot 和 Spring WebFlux 中使用“功能 bean 定义 Kotlin DSL”?