打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spring的AbstractRoutingDataSource 实现 数据源DB的动态切换
userphoto

2013.10.16

关注
最近要为公司多个游戏做类似的统计功能,考虑到模块的复用性,决定做个动态数据源,根据不同的游戏参数切换不同的datasource。
网上查了下,spring2.0以后增加了AbstractRoutingDataSource这个东西。下面是实现方法
首先看下AbstractRoutingDataSource类结构,继承了AbstractDataSource
Java代码  
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
}
既然是AbstractDataSource,当然就是javax.sql.DataSource的子类,于是我们自然地回去看它的getConnection方法:
Java代码  
public Connection getConnection() throws SQLException {
return determineTargetDataSource().getConnection();
}
原来奥妙就在determineTargetDataSource()里:
Java代码  
/**
* 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
Java代码  
<bean id="onlineDynamicDataSource" class="com.xx.stat.base.dynamic.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="xx" value-ref="dataSourceXX"/>
<entry key="yy" value-ref="dataSourceYY"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource"/>
</bean>
观察上面的配置文件,发现我们配置的是targetDataSources和defaultTargetDataSource
Java代码  
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
Java代码  
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
Java代码  
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();
}
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Spring 实现数据库读写分离(AbstractRoutingDataSource)
微服务架构springboot读写分离这么难写么?我就觉得很简单
SpringBoot + Mybatis 多数据源配置
SpringBoot 实现动态切换多数据源,这么做才叫优雅!
Hibernate 与 Spring 多数据源的配置
Spring多数据源的配置和使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服