Announcement Announcement Module
Collapse
No announcement yet.
Dynamic Property Configuration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynamic Property Configuration

    Hi,

    What I am looking to achieve is kinda of like the PropertyPlaceholderConfigurer, in that I would like configuration values within my bean config to be derived from external values.

    While the PropertyPlaceholderConfigurer allows for setting values from a list of property files, I would like it to be derived from a configuration hierarachy - implemented using a similiar pattern to the Chain-of-Command structure.

    I have achieved this using a bean implementing the MethodInvokingFactoryBean; but I realise that this is both cludgy and dependant upon a perscribed bean heirachy.

    eg:
    Configuration Setup:
    Code:
        <!-- Cache Configuration Source -->
        <bean id="CacheConfigSource" class="jolyon.spring.services.config.EHCacheConfigSource">
            <property name="cache">
                <bean id="ConfigCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
                    <property name="cacheManager">
                        <bean id="EhCacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
                    </property>
                    <property name="cacheName">
                        <value>ConfigCache</value>
                    </property>
                    <property name="eternal">
                        <value>false</value>
                    </property>
                    <property name="timeToLive">
                        <value>120</value>
                    </property>
                    <property name="timeToIdle">
                        <value>120</value>
                    </property>
                    <property name="diskPersistent">
                        <value>false</value>
                    </property>
                    <property name="maxElementsInMemory">
                        <value>10000</value>
                    </property>
                    <property name="overflowToDisk">
                        <value>true</value>
                    </property>
                    <property name="diskExpiryThreadIntervalSeconds">
                        <value>120</value>
                    </property>
                </bean>
            </property>
        </bean>
        <!-- Hibernate Configuration Source -->
        <bean id="HibernateConfigSource" class="jolyon.spring.services.config.HibernateConfigSource">
            <property name="sessionFactory">
                <ref bean="sessionFactory"/>
            </property>
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
        </bean>
        <!-- Property File Configuration Source -->
        <bean id="PropertyFileConfigSource" class="jolyon.spring.services.config.PropertyFileConfigSource">
            <property name="basenames">
                <list>
                    <value>config</value>
                </list>
            </property>
        </bean>
        <!-- Configuration Bean -->
        <bean id="ConfigBeanTarget" class="jolyon.spring.services.config.ConfigBeanImpl">
            <property name="configSourcesNames">
                <list>
                    <value>CacheConfigSource</value>
                    <value>PropertyFileConfigSource</value>
                </list>
            </property>
        </bean>
        <bean id="ConfigBean" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces">
                <value>jolyon.spring.services.config.ConfigBean</value>
            </property>
            <property name="target">
                <ref bean="ConfigBeanTarget"/>
            </property>
        </bean>
        <bean id="StringConfigSetting" abstract="true" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetObject">
                <ref bean="ConfigBean"/>
            </property>
            <property name="targetMethod">
                <value>getConfigString</value>
            </property>
            <property name="singleton">
                <value>false</value>
            </property>
        </bean>
        <bean id="ListConfigSetting" abstract="true" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetObject">
                <ref bean="ConfigBean"/>
            </property>
            <property name="targetMethod">
                <value>getConfigList</value>
            </property>
            <property name="singleton">
                <value>false</value>
            </property>
        </bean>
    Property extract:
    Code:
                    <property name="outputFileName">
                        <bean parent="StringConfigSetting">
                            <property name="arguments">
                                <value>GenerateCourseCategoryDataFile.OutputFileName</value>
                            </property>
                        </bean>
                    </property>
    I am unable to find out what precisely I need to do to convert my ConfigBean instance into operating like a PropertyPlaceholderConfigurer, therefore allowing configuration settings to be pulled from a hierachy, without implementation linkages and verbose bean configuration.

    Is this possible? Short of implementing an entire bean factory postprocessor for this specific task.

  • #2
    You may need to implement the BeanFactoryPostProcessor interface.

    HTH.

    Comment


    • #3
      I did that already using the jakarta commons configuration library.

      All i did was extending the PropertyPlaceHolder with an property accepting 'org.apache.commons.configuration.Configuration'.

      Next i overwrote the resolvePlaceholder with
      Code:
      protected String resolvePlaceholder(String placeholder, Properties properties) {
      	String value = null;
      	if ( true == this.configurationOverwrite && null != this.configuration ) {
      		value = resolvePlaceholder( placeholder, this.configuration );
      	}
      	if ( null == value ) {
      		value = super.resolvePlaceholder( placeholder, properties );
      	}
      	if ( null == value && null != this.configuration ) {
      		value = resolvePlaceholder( placeholder, this.configuration );
      	}
      	return( value );
      }
      That does the trick for a singel jakarta common configuration bean. To be a little bit more convenient i additionally provide an CompositeConfigurationWrapper which extends the CompositeConfiguration class to be a little bit more convenient in combining several configuration resources using the constructor-arg pattern.

      Code:
      public class CompositeConfigurationWrapper extends CompositeConfiguration {
      
      	protected static final Log log = LogFactory.getLog( CompositeConfigurationWrapper.class );
      	
      	/**
      	 * Standard constructor.
      	 * 
      	 * Nothing special about this one.
      	 *
      	 */
      	public CompositeConfigurationWrapper() {
      		super();
      	}
      
      	/**
      	 * Constructor for usage in spring context definitions.
      	 *  
      	 * @param configurations A list of org.apache.commons.configuration.Configuration instances.
      	 */
      	public CompositeConfigurationWrapper( List configurations ) {
      		super();
      		this.addConfigurations( configurations );
      	}
      	
      	/**
      	 * Setter for a list of configuration beans.
      	 * 
      	 * @param configurations A list of org.apache.commons.configuration.Configuration instances.
      	 */
      	public void addConfigurations( List configurations ) {
      		if ( log.isDebugEnabled() ) {
      			log.debug( "[addConfigurations] BEGIN" );
      		}
      		synchronized( this ) {
      			for ( Iterator i = configurations.iterator(); i.hasNext(); ) {
      				super.addConfiguration( (Configuration)i.next() );
      			}
      		}
      		if ( log.isDebugEnabled() ) {
      			log.debug( "[addConfigurations] END" );
      		}
      	}
      }
      Cascading configuration using placeholders is now very easy.

      greets
      Sebastian

      Comment


      • #4
        Btw, Spring Modules (springmodules.dev.java.net) already has support for Jakarta Commons. There will be a new release (0.3) in the very near future.

        Comment

        Working...
        X