Blog maintained by TechnoGems

Tuesday, October 5, 2010

spring apache commons configuration

I was surprised to find out that integrating the apache commons configuration with the spring framework is not trivial.  I was hoping that there will be one bean that we can use out of the box within the spring framework or the apache commons framework and we set that as a property in the bean and we can go on.  Unfortunately it was not that easy.   It takes a few steps to get this working.  Here are the steps that you need to follow to get this integration working:

1) Define the properties beans in spring xml file (typically ApplicationConfiguration.xml file)
 as follows: 
 <!-- Apache Commons Configuration Composite configuration -->
    <bean id="configurations"
        class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
        <property name="configurations">
            <list>
                <bean class="org.apache.commons.configuration.PropertiesConfiguration">
                    <constructor-arg type="java.net.URL"
                        value="classpath:myconfiguration.properties" /> 
                    <property name="reloadingStrategy">
                        <bean class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
                    </property>
                </bean>
                <bean class="org.apache.commons.configuration.SystemConfiguration"/>               
            </list>
        </property>
        <!-- define configuration as a set of spring resources -->
    </bean>
    <bean id="configuration" class="org.apache.commons.configuration.Configuration" factory-bean="&amp;configurations" factory-method="getConfigurations"/>

2) Define a bean with the getter and setter that returns/accepts an array of org.apache.commons.configuration.Configuration class.  To make it easier for the rest of the code to get the configuration easy, you may want to add a utility method in there to return the combined Configutaion.  Here is an example:

private Configuration configs[] ;
private ConfigurationBuilder cfgBuilder ;

    public Configuration[] getConfigs() {
        return configs;
    }

    public void setConfigs(Configuration[] configs) {
        this.configs = configs;
        cfgBuilder = new ConfigurationBuilder();
        for (Configuration cgf: configs) {
            cfgBuilder.addConfiguration(cgf);
        }
    }

    public Configuration getConfig() {
        return cfgBuilder.getConfiguration();
    }
3) Define the bean properties in the spring xml file.  I suggest, that you may want to define the above method in a base class of all your beans and define it as an abstract bean.  This will enable you to use the properties in all your beans without having to define the properties in every bean.  Here is an example:
  <bean id="baseActionBean"  class="com.my.company.BaseAction"  abstract="true" >
            <property name="configs" ref="configuration" />
        </bean>
         <bean id="logonClass" class="com.my.company.UsefulAction"  parent="baseActionBean">
         </bean>
4)  Add the necessary libraries if you do not have them already.  Here is the list of jars you will need.
commons-lang-*.jar
commons-configuration*.jar
spring-modules-jakarta-commons*.jar
 With these changes, you should be able to use the properties in your beans with a code as simple as getConfig().getString("propertyKey")

No comments: