Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: sharing list and map definitions?

  1. #1
    Join Date
    Jun 2005
    Location
    New York
    Posts
    5

    Default sharing list and map definitions?

    Hi,

    I have several beans each containing a list that shares many (over 50) entries. Is there any way to inherit these common entries to reduce clutter?

    For example:

    (current situation simplified)


    <bean id="logicalConnection" class="xxx.MessageDefinition">
    <property name="fields">
    <list>
    <ref bean="userNumField"/>
    <ref bean="passField"/>
    </list>
    </property>
    </bean>
    <bean id="logicalConnectionReply" class="xxx.MessageDefinition">
    <property name="fields">
    <list>
    <ref bean="userNumField"/>
    <ref bean="passField"/>
    <ref bean="infoField"/>
    </list>
    </property>
    </bean>


    Desired:
    something like

    <list id="base-list">
    <ref bean="userNumField"/>
    <ref bean="passField"/>
    </list>
    <bean id="logicalConnection" class="xxx.MessageDefinition">
    <property name="fields" value-ref="base-list"/>
    </property>
    </bean>
    <bean id="logicalConnectionReply" class="xxx.MessageDefinition">
    <property name="fields">
    <list extends="base-list">
    <ref bean="infoField"/>
    </list>
    </property>
    </bean>

  2. #2

    Default

    We achieved what you need by simply extending the capabilities of ListFactoryBean and MapFactoryBean.

  3. #3
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    You can provide a reuse-able bean definition for a List implementation, such as:
    Code:
    <beans>
    
    	<bean id="base-list" class="java.util.ArrayList">
    		<constructor-arg>
    			<list>
    				<value>item1</value>
    				<value>item2</value>
    			</list>
    		</constructor-arg>
    	</bean>
    	
    	<bean id="needsList1" class="xyz.NeedsList">
    		<property name="list" ref="base-list"/>
    	</bean>
    
    	<bean id="needsList2" class="xyz.NeedsList">
    		<property name="list" ref="base-list"/>
    	</bean>
    		
    </beans>
    Or another option is bean-inheritance: injecting the list into an abstract parent bean and then having your other bean definitions inherit from that by using the "parent" attribute.

    Out of curiosity, are you using DI for the individual elements of the List?

  4. #4

    Default

    We chose to extend Spring so that we can reuse a base set of items and then add to it for each custom bean.

  5. #5
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by wallychang
    Is there any way to inherit these common entries to reduce clutter?
    If you are instantiating the many instances of the same class then you can inherit configuration:

    Code:
      <bean id="exampleClass" abstract="true" class="yourClass">
        <property name="xyz" value="abc"/>
      </bean>
    
      <bean id="aRealClass" parent="exampleClass"/>
    This won't really help in your situation though

    I don't think there is anything out of the box that will help you, but the following might be a good start:

    Code:
    <bean id="baseList" class="org.springframework.beans.factory.config.ListFactoryBean">
      <property name="sourceList">
        <list>
          <value>someProperty</value
          <value>someOtherProperty</value
        </list>
      </property>
    </bean>
    
    <bean id="yourBean" class="yourClass">
      <property name="yourProperty" ref="baseList"/>
    </bean>
    That will get you someway, but I don't know of any factory bean to add to the existing list, however the following will do:

    Code:
    public class ListAddingBeanBean implements FactoryBean {
      private final List lists;
      public ListAddingBeanBean (final List theLists) {
        this.lists = theLists;
      }
    
      public Object getObject() {
        // as we are singleton, we could cache this :)
        List newList = new ArrayList();
        for (Iterator i = lists.iterator; i.hasNext(); ) {
          List list = (List) i.next();
          newList.addAll(list);
        }
        return newList;
      }
    
      public Class getObjectType() {
        return List.class;  // could be parameterisable of course.
      }
      public boolean isSingleton() {
        return truel
      }
    }
    This would then be wired up:

    Code:
      <bean id="someOtherClass" class="yourClassAgain">
        <property name="somethingTakingAList">
          <bean class="ListAddingFactoryBean">
            <list>
              <ref local="baseList"/>
              <list>
                <value>abc</value>
                <value>def</value>
              </list>
            </list>
          </bean>
        </property>
      </bean>
    I have *no* idea whether the above will work, and I am sure, after having typed all that that there *must* be a more elegant solution

    Anyways; subject to someone pointing out a better way; I hope it helps
    Last edited by Colin Yates; Feb 10th, 2006 at 01:24 PM.

  6. #6
    Join Date
    Jun 2005
    Location
    New York
    Posts
    5

    Default

    Quote Originally Posted by Mark Fisher
    You can provide a reuse-able bean definition for a List implementation, such as:
    Code:
    <beans>
    
    	<bean id="base-list" class="java.util.ArrayList">
    		<constructor-arg>
    			<list>
    				<value>item1</value>
    				<value>item2</value>
    			</list>
    		</constructor-arg>
    	</bean>
    	
    	<bean id="needsList1" class="xyz.NeedsList">
    		<property name="list" ref="base-list"/>
    	</bean>
    
    	<bean id="needsList2" class="xyz.NeedsList">
    		<property name="list" ref="base-list"/>
    	</bean>
    		
    </beans>
    Or another option is bean-inheritance: injecting the list into an abstract parent bean and then having your other bean definitions inherit from that by using the "parent" attribute.
    The problem with this approach is that needsList1 and needsList2 have the same items; what if there were only one or two different items between the lists? (I'm sorry if my initial post wasn't clear about this problem).

    On the other hand, would this be possible by using the init-method="addAll" attribute?

    Quote Originally Posted by Mark Fisher
    Out of curiosity, are you using DI for the individual elements of the List?
    Yes, each element in the list has its own attributes.

  7. #7
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by wallychang
    The problem with this approach is that needsList1 and needsList2 have the same items; what if there were only one or two different items between the lists? (I'm sorry if my initial post wasn't clear about this problem).
    See my post above with the ListAddingFactoryBean

    On the other hand, would this be possible by using the init-method="addAll" attribute?
    The problem is that (I think) the list is passed by reference; so you would be updating the original list. Also; how would you specify the parameters.

    Did the solution in my post not work for you?

  8. #8
    Join Date
    Jun 2005
    Location
    New York
    Posts
    5

    Default

    Quote Originally Posted by yatesco
    See my post above with the ListAddingFactoryBean

    The problem is that (I think) the list is passed by reference; so you would be updating the original list. Also; how would you specify the parameters.
    Sorry , I was confusing it with the behavior of the factory-method attribute, where you can specify constructor arguments.

    Quote Originally Posted by yatesco
    Did the solution in my post not work for you?
    I wanted to see if there was any way to acheive the same functionality without creating a custom factory bean, but it seems that I am out of options, so I'll try your approach Thanks!
    Last edited by wallychang; Feb 10th, 2006 at 03:21 PM.

  9. #9
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    I was browsing the 2.0 reference the other day. It appears to have this new collection merging feature. See Section 3.3.3.4, 2.0 M2 reference. (Of course this won't help you if you are stuck with 1.x.)
    --Jing Xue

  10. #10
    Join Date
    Oct 2004
    Location
    Fareham, England
    Posts
    313

    Default

    Hi

    Just letting ya'll know that the collection merging support mentioned by manifoldronin is going to be backported into the 1.2.x branch.

    Cheers
    Rick

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •