The challenge
Make spring applications easily adaptable for diffent target environments (like "test", "staging" and "live"), without having to change the applicationContext.xml file. Nice to have: enable system administrators to change the configuration without repackaging.
As always the spring framework offers a couple of excellent solutions for this.
PropertyPlaceholderConfigurer
The PropertyPlaceholderConfigurer provides runtime replacement of variables like ${dbname} in the application context xml. The downside of this solution is that you always have to provide all the values for all the variables, otherwise a BeanDefinitionStoreException will be thrown.
That is why I prefer
PropertyOverrideConfigurer
PropertyOverrideConfigurer enables you to override existing properties in the context file. The key is the reference to the property (<bean-id>.<property-name>) and the value is the value to set, eg.
dataSource.jdbcUrl=jdbc:postgresql://<hostname>/<databasename>
The PropertyOverrideConfigurer needs to be defined as the first bean in the context.xml file.
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer" lazy-init="false"> <property name="locations"> <list> <value>classpath:deploy.properties</value> <value>file:${user.dir}/deploy.properties</value> </list> </property> <property name="ignoreResourceNotFound" value="true"/> <property name="ignoreInvalidKeys" value="true"/> </bean>
Note the following details:
- lazy-init="false" otherwise the bean will never be created and executed
- locations property enables you to load a file outside the application directory