我有两个使用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),但不适用于那些生成的列表。
答案 0 :(得分:2)
在检查了与SpEL相关的解决方案(how to extend a list in 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>
的java:
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的解决方案消除了一个错误。谢谢!
答案 1 :(得分:2)
Java @Configuration
FTW:
@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;
}
}
更少的样板。
答案 2 :(得分:2)
上面的ListMergerFactoryBean解决方案存在一个sublte错误。
配置:
<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方法会改变它,因此即使bean工厂不是单例,也会为ListMergerFactoryBean的所有用户改变它。解决方法是不重复使用listOfLists中的第一个列表:
@Override
public List getObject() throws Exception {
List mergedList = new ArrayList();
for (List list : listOfLists) {
mergedList.addAll(list);
}
return mergedList;
}