2013-01-25 137 views
2

我有兩個使用FactoryBean生成的列表,我想用這兩個合併版本初始化一個bean。有沒有辦法做到這一點?Spring集合合併

<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

無法您只需注入和listA的成數組listB第三豆,並使用Java代碼合併兩個列表? –

+0

對不起,這是一個討厭的,具體的解決方案... – BTakacs

+0

可能的重複[有沒有辦法在spring配置文件中重新使用?](http://stackoverflow.com/questions/12760436/is-there-a-way-to-re-use-a-utillist-in-spring-configuration-file) –

回答

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

} 

少得多的樣板。

+0

似乎我需要更多地關注基於註釋的配置:此代碼更簡潔和更好。謝謝 – BTakacs

2

檢查規劃環境地政司相關解決方案(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; 
} 

}

U PDATE:我用Aron Bartle的解決方案消除了一個錯誤。謝謝!

+1

所以你在最後實現了我討厭的特定解決方案;-) –

+1

不,我用一個自定義FactoryBean來做合併並將合併後的集合注入到第三個bean中:-) – BTakacs

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> 

有了這個配置,當豆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; 
} 
+0

你說得對。感謝修復! – BTakacs