Announcement Announcement Module
Collapse
No announcement yet.
Merging bean properties defined in two separate files Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Merging bean properties defined in two separate files

    Hi!

    I'm using Spring to wire-up an application with many optional components, configured by user properties. As spring lacks any sort of conditional processing (probably for good reasons), I have decided to give each optional component its own bean definition file. When creating the application context, I can then include only those files that correspond to the enabled components.

    This ends up working well for many cases, however I'm having trouble when the configuration for a particular component requires modifying the properties of one of the non-optional objects.

    What I would like to do is something like this:

    Code:
    <!-- applicationContext-main.xml -->
    
    <bean id="tabManager" class="foo.bar.TabManager" />
      <property name="tabs">
        <list>
          <bean class="foo.bar.CustomerTab" />
          <bean class="foo.bar.ProviderTab" />
        </list>
      </property>
    </bean>
    Code:
    <!-- applicationContext-salesPerson.xml (optional) -->
    
    <bean id="tabManager" parent="tabManager" />
      <property name="tabs">
        <list merge="true">
          <bean class="foo.bar.SalesPersonTab" />
        </list>
      </property>
    </bean>

    In case like this, there would be only one TabManager bean, named tabManager, which would have 2 or 3 tabs in it, depending on whether or not the applicationContext-salesPerson.xml file was included.

    The XML above doesn't work, as Spring doesn't like beans with the same value for id and parent. I can't figure out how to override a bean, but keep some of the properties from the previous definition. Using child bean definitions as described in the documentation results in two separate beans, when all I want to do is modify the parent bean to include my extra properties.

    I would prefer not to make the SalesPersonTab depend on the TabManager, but as a last resort I could have SalesPersonTab include TabManager as a constructor parameter, and add itself to the list programmatically.

    Any suggestions are appreciated.

    Thanks,

    Kor

  • #2
    By creating my own implementation of the DefaultListableBeanFactory, I was able to make the above application contexts merge together.

    Code:
    class MergingListableBeanFactory extends DefaultListableBeanFactory
    {
      public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException
      {
        if (beanDefinition instanceof ChildBeanDefinition)
        {
          ChildBeanDefinition cbd = (ChildBeanDefinition) beanDefinition;
          if (beanName.equals(cbd.getParentName()))
          {
            AbstractBeanDefinition pbd = (AbstractBeanDefinition) super.getBeanDefinition(beanName);
            pbd.overrideFrom(cbd);
            return;
          }
        }
        super.registerBeanDefinition(beanName, beanDefinition);
      }
    }

    Comment

    Working...
    X