Wednesday, February 24, 2010

Customozing Spring's Routing Datasource

Changing the data source of your application dynamically at runtime is a very desirable feature for complex enterprise applications and frameworks. If you are using Spring, one of the viable options is Spring's AbstractRoutingDataSource, which allows dynamic data sources based on a lookup key. It uses the well known Decorator pattern to provide a javax.sql.DataSource instance dynamically.

The following article by Mark Fisher from Spring team clearly explains how to go about it:
http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

The default usage of Spring's AbstractRoutingDataSource is something as follows:
i) You have a set of data sources among which you want to switch dynamically.
ii) You have a well known dynamic key that can pick the right data source for you.

But what if you want to change the set of data sources themselves dynamically? The default usage of AbstractRoutingDataSource won't allow this. After digging into Spring code for some time I found that the following piece of code can do the job.

public class RoutingDataSource extends AbstractRoutingDataSource {
private Map targetDataSources = new HashMap();
public void setTargetDataSources(Map targetDataSources) {
this.targetDataSources = targetDataSources;
}

@Override
protected DataSource determineTargetDataSource() {
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = (DataSource)this.targetDataSources.get(lookupKey);
if (dataSource == null) {
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
}
return dataSource;
}

@Override
protected Object determineCurrentLookupKey() {
return /*a lookup key that can pick the actual datasource from the Map*/;
}

@Override
public void afterPropertiesSet() {
// do nothing
// overridden to avoid datasource validation error by Spring
}
}

1 comment: