3

我有两个使用 FactoryBean 生成的列表,我想用这两个列表的合并版本初始化一个 bean。有没有办法做到这一点?

<bean id="listA" class="XFactoryBean" >
  ...
</bean>
<bean id="listB" class="YFactoryBean">
  ...
</bean>
<bean >
  <property name="AwithB" ...>
</bean>

有一个适用于静态列表的解决方案(http://vikdor.blogspot.hu/2012/10/using-collection-merging-in-spring-to.html),但不适用于那些生成的列表。

4

3 回答 3

3

Java @ConfigurationFTW:

@Configuration
public class Config {

    @Resource
    private List listA;

    @Resource
    private List listB;

    @Bean
    public List AwithB() {
        List mergedList = new ArrayList(listA);
        listB.addAll(listB);
        return mergedList;
    }

}

少得多的样板。

于 2013-01-25T19:48:02.380 回答
2

检查 SpEL 相关解决方案(如何在 spring config 中扩展列表)并扩展 ListFactoryBean(http://ericlefevre.net/wordpress/2008/04/02/merging-lists-in-a-spring-configuration- file/ ) 我想出了以下解决方案:

配置:

<bean id="AwithB" class="com.util.ListMergerFactoryBean">
    <property name="listOfLists">
        <list>
            <ref bean="listA" />
            <ref bean="listB" />
        </list>
    </property>
</bean>

爪哇:

public class ListMergerFactoryBean implements FactoryBean<List> {

private List<List> listOfLists;

@Override
public List getObject() throws Exception {
    List mergedList = new ArrayList();
    for (List list : listOfLists) {
            mergedList.addAll(list);
    }
    return mergedList;
}

@Override
public Class<?> getObjectType() {
    return (new ArrayList()).getClass();
}

@Override
public boolean isSingleton() {
    return false;
}

public void setListOfLists(List<List> listOfLists) {
    this.listOfLists = listOfLists;
}

}

更新:我使用 Aron Bartle 的解决方案消除了一个错误。谢谢!

于 2013-01-25T12:09:33.500 回答
2

上面的 ListMergerFactoryBean 解决方案存在一个微妙的错误。

配置:

<util:list id="listA" value-type="java.lang.String">
  <value>fooA</value>
  <value>barA</value>
</util:list>
<util:list id="listB" value-type="java.lang.String">
  <value>fooB</value>
  <value>barB</value>
</util:list>
<util:list id="listC" value-type="java.lang.String">
  <value>fooC</value>
  <value>barC</value>
</util:list>
<bean id="AwithB" class="com.util.ListMergerFactoryBean">
  <property name="listOfLists">
    <list>
        <ref bean="listA" />
        <ref bean="listB" />
    </list>
  </property>
</bean>
<bean id="AwithC" class="com.util.ListMergerFactoryBean">
  <property name="listOfLists">
    <list>
        <ref bean="listA" />
        <ref bean="listC" />
    </list>
  </property>
</bean>

使用此配置,当 bean AwithB 具有 AwithC 的预期内容时,您可能会感到惊讶。ListA 是一个单例,getObject 方法会更改它,因此会为 ListMergerFactoryBean 的所有用户更改它,即使 bean 工厂不是单例。解决方法是不重复使用 listOfLists 中的第一个列表:

@Override
public List getObject() throws Exception {
  List mergedList = new ArrayList();
  for (List list : listOfLists) {
    mergedList.addAll(list);
  }
  return mergedList;
}
于 2014-08-25T16:43:03.710 回答