geeky · java

Spring loading properties from database with a twist

Watched the spring framework 3.1 webinar today and it was pretty interesting.

Anyway, at work we are trying to possibly load property values from a database to resolve some tension between the developers and system specialists.

I played a little bit at home as how we would set this up. This is not a new issue obviously; many have solved it previously. I did it partly as an exercise to familiarize myself with cygwin, maven and intellij as they are the new tools I will be using at my new job 🙂

The things to accomplish

  • Load properties to replace placeholders in spring config from both .properties file and a database table
  • The configuration table will contain properties for more than one application
  • Use another .properties file to initialize the datasource for the database configuration table.

Main libraries used

  • Spring (3.0.3.RELEASE)
  • H2 database (1.1.118)
  • Spring modules (0.8a)
  • Commons-configuration (1.6)
  • JUnit (4.5)
  • Spring-test (3.0.3.RELEASE)

I first created a simple project via maven. I assume you have maven installed with shell/batch access.

mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.0 -DgroupId=net.pureessence -DartifactId=DatabaseConfiguration -Dversion=1.0 -Dpackage=net.pureessence.example

How I wired up the configuration datasource

I created a factory to create the datasource using org.apache.commons.dbcp.BasicDataSourceFactory.createDataSource(properties) and loaded the initial datasource properties statically via the class loader. For more information on the property keys used by BasicDataSourceFactory.createDataSource, visit this test case.

public static DataSource createDataSource(String propertyFilename) throws Exception {
    Properties properties = new Properties();
    InputStream in = PropertiesDataSourceFactory.class.getClassLoader().getResourceAsStream(propertyFilename);
    properties.load(in);
    in.close();

    return BasicDataSourceFactory.createDataSource(properties);
}
<bean id="dataSource" class="net.pureessence.example.PropertiesDataSourceFactory" factory-method="createDataSource">
    <constructor-arg type="java.lang.String" value="databaseForConfiguration.properties" />
</bean>

How I wired up the configuration

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="classpath:env.properties"
    p:properties-ref="commonsConfigurationFactoryBean"/>

<bean id="commonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
    <constructor-arg ref="databaseConfiguration"/>
</bean>

<bean id="databaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
    <constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
    <constructor-arg name="table" value="configuration"/><!— configuration table name —>
    <constructor-arg name="nameColumn" value="application"/><!— name column —>
    <constructor-arg name="keyColumn" value="key"/><!— key column —>
    <constructor-arg name="valueColumn" value="value"/><!— value column —>
    <constructor-arg name="name">
    <util:constant static-field="net.pureessence.example.Constants.APPLICATION_ONE"/>
    </constructor-arg><!— name (specific configurations) —>
</bean>

<bean id="person" class="net.pureessence.example.Person"
    p:firstName="${first.name}"
    p:lastName="${last.name}"
    p:email="${email}"
    p:car="${car}" />

The property key “car” is loaded from env.properties while “first.name”, “last.name” and “email” properties are loaded from the database table.

Why it works

In order to load configuration/placeholders from a database table, the datasource has to be instaniated prior to the instaniation of all of the other beans with placeholders. The databsource factory creates the instance of the datasource via another properties file loaded outside of spring.

Note about the tests

The tests are set up to load the H2 database with the configuration table & data prior to the loading of the spring context in order for it to work.

Source code

It contains both intellij and eclipse project files. You should have the m2eclipse plugin for eclipse installed in order to pull down the jars in pom.xml.

»>Git Repository

2 thoughts on “Spring loading properties from database with a twist

  1. Thanks a lot for this tutorial. This works for me. Just wanted to know if this works with @Value annotation for the properties read from database.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s