Reputation: 1471
I have defined a with some "common" values. How can I extend the common list by additional values to various new beans?
<util:list id="myCommonList" list-class="java.util.LinkedList">
<bean .../>
<bean .../>
<bean .../>
<bean .../>
</util:list>
<bean id="extension" parent="myCommonList">
<bean ref="additionalValue"/>
</bean>
Will this overwrite the list or extend it?
Upvotes: 23
Views: 29448
Reputation: 327
To append list2's elements to list1 use the following spring config.
<util:list id="list1">
<value>1</value>
<util:list>
<util:list id="list2">
<value>3</value>
<value>5</value>
<util:list>
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="list1" />
<property name="targetMethod" value="addAll" />
<property name="arguments" ref="list2" />
</bean>
Upvotes: 4
Reputation: 1
You can overwrite or add any other bean in this list by following the below snippet.
For example: this is your bean which needs to be injected in the AAA util:list mentioned below.
<bean id = "BBB" class=""/>
<util:list id="AAA"/>
<bean id="AAAListMergeDirective" depends-on="AAA"
parent="listMergeDirective" >
<property name="add" ref="BBB" />
</bean>
Upvotes: 0
Reputation: 430
Based on skaffman's answer, you can achive this way:
<util:list id="parent">
<value>X</value>
</util:list>
<bean id="child" parent="parent" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list merge="true">
<value>Y</value>
</list>
</property>
</bean>
Upvotes: 11
Reputation: 642
Today I was having this issue too. For me the acceptable solution was to use SpEL and while SpEL doesn't supports multiple statements - create two auxiliary classes that appends lists.
Context might be implemented like this:
<util:list id="list1">
<value>str1</value>
<value>str2</value>
</util:list>
<util:list id="list2">
<value>str3</value>
<value>str4</value>
</util:list>
<bean ...>
<property name="propertyThatRequiresMergedList"
value="#{ new x.y.springs.StringListsMerger().merge(@list1, @list2) }" />
</bean>
And classes:
package x.y.springs;
import java.util.List;
public abstract class ListsMerger<T extends List> {
public T merge(T ... lists) {
T container = createContainer();
for (T list : lists) {
container.addAll(list);
}
return container;
}
public abstract T createContainer();
}
package x.y.springs;
import java.util.ArrayList;
import java.util.List;
public class StringListsMerger extends ListsMerger<List<String>> {
@Override
public List<String> createContainer() {
return new ArrayList<String>();
}
}
Upvotes: 1
Reputation: 8281
According to this JIRA; there is no trivial solution for this (currently, but hopefully in 3.1 there will be), though there are several workarounds; e.g. this one.
Upvotes: 2
Reputation: 403581
You can do it, but not using <util:list>
, which is just a convenience syntax. The container does provide a "collection merging" function, but you have to use the "old" style:
<bean id="parent" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<value>X</value>
</list>
</property>
</bean>
<bean id="child" parent="parent" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list merge="true">
<value>Y</value>
</list>
</property>
</bean>
Upvotes: 36