Wednesday, November 21, 2012

Simple and effective: Spring and customizable configuration

The problem

The problem is to have the configuration customization possible after deployment. There are settings your hosting department for whatever reason will not let you know (like database password for instance). This fits really nicely to the ways Spring handles configuration.

The solution

The solution in Spring 3.1.x is to use the <context:property-placeholder> tag configured as follows:
    <context:property-placeholder 
     system-properties-mode="OVERRIDE"
     ignore-resource-not-found="true"
     location="
      classpath:defaults.properties,
      file:${config.location:/etc/example.properties}" />

The explanation

First of all there have to be sensible defaults the application can work with. I personally favor them to be good for development so other developers can just get the application, execute mvn tomcat7:run and have it running in minutes rather than to fiddle with all the moving parts of configuration.
Now deployment and the hosting team is a totally different beast all together. They will always want to have things configured their way. <joke>I don't know why :)</joke>

So here we have it - on the classpath there are the defaults in defaults.properties. Now the second part is interesting. First of all it makes an assumption that hosting will follow the best practices and store configuration where it belongs, which in almost all Linux distros is the /etc/ folder. Here's the trick though: some admins will cut your fingers an inch shorter if you force them to put anything anywhere. Especially for that occasion the second option is there to save the day. It allows you to specify a JVM parameter -Dconfig.location=... for Spring to look for configuration options in a completely different place. Neat, ain't it? Finally the system-properties-mode="OVERRIDE" allows for in-place overrides using JVM system variables (the ones specified with -Dvariable=value)

I hope it'll save someone some precious time. I know it'll save me from re-inventing this solution time and time again.

No comments: