November 22, 2010

Spring Configuration Per Environment

Originally published 30 Jan 2008

It's common that configuration changes between environments (e.g., development, test, production).  For example, you'd definitely want a different DataSource URL depending on what environment you're running in.  Do you really want to hit the production database while developing?  Spring doesn't seem to support this per environment configuration out of the box (at least I've never been able to find it).  There's been a request for this feature for some time now (SPR-1876), but it's still open.

The reality is that properties files are the simplest and easiest way to configure an application, particularly for non-developers.  What I'd like to see is a PropertyPlaceholderConfigurer that can configure an application per environment.  This is what SPR-1876 is all about.  However, it suggests there be a file per environment.  As an alternative, I suggest a single properties file.  A single file containing all the properties would be the simplest to maintain.  Think of it.  I've got a new property.  Do I want to add it to three files or one?  If I want to see all the possible values of a property, do I want to open and hunt through three files or one?

Grails supports the idea of grouping all the properties together, but it uses multiple configuration files (Config.groovy and DataSource.groovy) depending on the property.

Okay, so here's what I propose the properties file look like:

# this is the default value for all environments
my.prop=defaultValue
# but in the production environment, it is different
[production].my.prop=productionValue
 
# here's another property with no default
# (adapted example from the Grails user guide)
[development].dataSource.url=jdbc:hsqldb:mem:devDB
[test].dataSource.url=jdbc:hsqldb:mem:testDb
[production].dataSource.url=jdbc:hsqldb:file:prodDb;shutdown=true
 
The context definition simply uses the property name without the environment and the custom per environment PropertyPlaceholderConfigurer provides the appropriate value:

<bean id="dataSource"
      class="org.springframework.jdbc.datasource...">
  <property name="url" value="${dataSource.url}" />
</bean>

So what are the downsides to this approach?  I suppose you can argue that a single properties file could be cluttered with details you don't care about.  For example, a production administrator may not care to see all the development and test values.

The other downside I can think of is forgetting to override a property.  That is, nothing reminds you that you have to override the DataSource URL for production.  It's content with using a default value.  The separate file approach would handle this because the property would be undefined.

So if I were reading this I'd say, "Spring is open source dude.  And those Spring guys are busy.  Go implement it and attach it to SPR-1876."  And if I get some time...

No comments:

Post a Comment