首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

利用AbstractRoutingDataSource兑现动态数据源切换

2012-09-17 
利用AbstractRoutingDataSource实现动态数据源切换最近要为公司多个游戏做类似的统计功能,考虑到模块的复

利用AbstractRoutingDataSource实现动态数据源切换

最近要为公司多个游戏做类似的统计功能,考虑到模块的复用性,决定做个动态数据源,根据不同的游戏参数切换不同的datasource。

网上查了下,spring2.0以后增加了AbstractRoutingDataSource这个东西。下面是实现方法

?

首先看下AbstractRoutingDataSource类结构,继承了AbstractDataSource

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {}
?

既然是AbstractDataSource,当然就是javax.sql.DataSource的子类,于是我们自然地回去看它的getConnection方法:

public Connection getConnection() throws SQLException {return determineTargetDataSource().getConnection();}

?原来奥妙就在determineTargetDataSource()里:

/** * Retrieve the current target DataSource. Determines the * {@link #determineCurrentLookupKey() current lookup key}, performs * a lookup in the {@link #setTargetDataSources targetDataSources} map, * falls back to the specified * {@link #setDefaultTargetDataSource default target DataSource} if necessary. * @see #determineCurrentLookupKey() */protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");Object lookupKey = determineCurrentLookupKey();DataSource dataSource = (DataSource) this.resolvedDataSources.get(lookupKey);if (dataSource == null) {dataSource = this.resolvedDefaultDataSource;}if (dataSource == null) {throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");}return dataSource;}

这里用到了我们需要进行实现的抽象方法determineCurrentLookupKey(),该方法返回需要使用的DataSource的key值,然后根据这个key从resolvedDataSources这个map里取出对应的DataSource,如果找不到,则用默认的resolvedDefaultDataSource

?

    <bean id="onlineDynamicDataSource" value-ref="dataSourceXX"/>                <entry key="yy" value-ref="dataSourceYY"/>             </map>          </property>          <property name="defaultTargetDataSource" ref="dataSource"/>      </bean>
?

观察上面的配置文件,发现我们配置的是targetDataSources和defaultTargetDataSource

?

public void afterPropertiesSet() {if (this.targetDataSources == null) {throw new IllegalArgumentException("targetDataSources is required");}this.resolvedDataSources = new HashMap(this.targetDataSources.size());for (Iterator it = this.targetDataSources.entrySet().iterator(); it.hasNext();) {Map.Entry entry = (Map.Entry) it.next();Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());this.resolvedDataSources.put(lookupKey, dataSource);}if (this.defaultTargetDataSource != null) {this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);}}

?

下面就是我们自己实现的子类DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource{        @Override    public void setTargetDataSources(Map targetDataSources) {        super.setTargetDataSources(targetDataSources);    }        @Override    public Object unwrap(Class iface) throws SQLException {        return null;    }    @Override    public boolean isWrapperFor(Class iface) throws SQLException {        return false;    }    @Override    protected Object determineCurrentLookupKey() {        String dataSourceName = DynamicDataSourceHolder.getDataSourceName();        return dataSourceName;    }

?

DynamicDataSourceHolder

public class DynamicDataSourceHolder {    private static final ThreadLocal<String> holder = new ThreadLocal<String>();        public static void putDataSourceName(String name){        holder.set(name);    }        public static String getDataSourceName(){        return holder.get();    }}
?

?

?

?

热点排行