Grey-Bearded Geek

Random Thoughts Of A Middle-Aged Software Engineer

Spring Collection Merging

April 23rd 2008

Spring has some really interesting, relatively new (since 2.x) features that have come in handy lately. I’ll talk about two of them here, which, when used together, are pretty powerful, and cut down on a lot of configuration xml:

First, <util:list> allows the specification of a List more succinctly. Previously, you had to write something like this:

<bean id="emails" 
    class="org.springframework.beans.factory.config.ListFactoryBean">
  <property name="sourceList">
      <list>
        <value>pechorin@hero.org</value>
        <value>raskolnikov@slums.org</value>
        <value>stavrogin@gov.org</value>
        <value>porfiry@gov.org</value>
      </list>
  </property>
</bean>

With the new 2.0 syntax, you can write this instead:

<util:list id="emails">
    <value>pechorin@hero.org</value>
    <value>raskolnikov@slums.org</value>
    <value>stavrogin@gov.org</value>
    <value>porfiry@gov.org</value>
</util:list>

By default, a java.util.List instance is created, but you can also specify a List subclass by using the ‘list-class’ attribute, like this:

<util:list id="emails" list-class="java.util.LinkedList">
    <value>jackshaftoe@vagabond.org</value>
    <value>eliza@thinkingmanscrumpet.org</value>
    <value>vanhoek@pirate.org</value>
    <value>d'Arcachon@nemesis.org</value>
</util:list>

This syntax is available for maps (<util:map>) and sets (<util:set>) as well. See the Spring Configuration documentation for the gory details.

The really great new feature that goes along with these is the concept of Collection Merging. You can configure a ‘parent’ collection, and then configure a ‘child’ collection, which will be the result of a merge between the parent collection’s members and the child’s members.

Here’s the example (for property collections) from the Spring documentation:

<beans>
<bean id="parent" abstract="true" class="example.ComplexObject">
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@somecompany.com</prop>
            <prop key="support">support@somecompany.com</prop>
        </props>
    </property>
</bean>
<bean id="child" parent="parent">
    <property name="adminEmails">
        <!-- the merge is specified on the *child* collection definition -->
        <props merge="true">
            <prop key="sales">sales@somecompany.com</prop>
            <prop key="support">support@somecompany.co.uk</prop>
        </props>
    </property>
</bean>
<beans>

Note that when there is a ‘conflict’ (a member is specified in both the parent and the child), the conflict will be resolved in favor of the child (i.e. the child’s specification for that member will be used, and the parent’s will be discarded).

There’s lots more good stuff there in addition to these - be sure to take a look!

blog comments powered by Disqus
Categories: Chariot, Spring