gist JS

Wednesday, December 06, 2006

Updated Spring Configuration

Here's an updated version of the HostPrecedingPropertyPlaceholderConfigurer that I introduced here.

This version makes for cleaner property files since you don't need to duplicate everything for each HOST, just the properties that are different.

The goal of this class is to be able to deploy your spring project to multiple hosts without needed to reconfigure / edit any properties files. This method makes it much easier to keep properties files in svn or cvs as well, because when Bob makes a change to the testDB server properties, he won't blow away your DB username etc when you checkout his changes.

package com.aavu.server.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

* HostPrecedingPropertyPlaceholderConfigurer
* Extends PropertyPlaceholderConfigurer to insert $hostname.property if
* the property name starts with HOST
* sample properties file:
* jdbc.user=live_user
* server.jdbc.url=jdbc:postgresql://db.host.com:5432/db
* server.magic.file.location=/var/magic_file
* jdbc.user=devel_user
* devel.jdbc.url=jdbc:postgresql://devel-db.host.com:5432/db
* devel.magic.file.location=c:\\var\magic_file
* my.property=a property referenced through a method besides
* HostPrecedingPropertyPlaceholderConfigurer
* <bean id="propertyConfigurer"
* class="com.util.spring.HostPrecedingPropertyPlaceholderConfigurer">
* <property name="location" value="classpath:config.properties" />
* </bean>
* <bean id="dataSource"
* class="com.mchange.v2.c3p0.ComboPooledDataSource"
* destroy-method="close">
* <property name="driverClass" value="${jdbc.driverClass}" />
* <property name="jdbcUrl" value="${HOST.jdbc.url}" /><!--Do a host lookup!-->
* <property name="user" value="${jdbc.user}" />
* <property name="password" value="${jdbc.password}" />
* </bean>
* @author Jeff Dwyer (blog) http://jdwyah.blogspot.com
public class HostPrecedingPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

private static Logger log = Logger.getLogger(HostPrecedingPropertyPlaceholderConfigurer.class);

protected String resolvePlaceholder(String placeholder, Properties props) {

try {

log.debug("Host: "+InetAddress.getLocalHost().getHostName()+" for property "+placeholder);
String replace = placeholder.replaceFirst("HOST", InetAddress.getLocalHost().getHostName());
return props.getProperty(replace);
return props.getProperty(placeholder);
} catch (UnknownHostException e) {
return null;


Viru said...

Thanks Jeff. I found this very useful. Good extension of the original idea.

eero said...
This comment has been removed by the author.
eero said...

Thank you Jeff for a great example. I took the liberty to enhance the code above a little further, so it falls back to a default property value, in case the host-specific value is not specified: