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

转载 2013年01月31日 14:23:05

原文地址:http://dsbjoe.iteye.com/blog/1176779


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

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

 

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

Java代码  收藏代码
  1. public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {  
  2.   
  3. }  
 

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

Java代码  收藏代码
  1. public Connection getConnection() throws SQLException {  
  2.     return determineTargetDataSource().getConnection();  
  3. }  

 原来奥妙就在determineTargetDataSource()里:

Java代码  收藏代码
  1. /** 
  2.  * Retrieve the current target DataSource. Determines the 
  3.  * {@link #determineCurrentLookupKey() current lookup key}, performs 
  4.  * a lookup in the {@link #setTargetDataSources targetDataSources} map, 
  5.  * falls back to the specified 
  6.  * {@link #setDefaultTargetDataSource default target DataSource} if necessary. 
  7.  * @see #determineCurrentLookupKey() 
  8.  */  
  9. protected DataSource determineTargetDataSource() {  
  10.     Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");  
  11.     Object lookupKey = determineCurrentLookupKey();  
  12.     DataSource dataSource = (DataSource) this.resolvedDataSources.get(lookupKey);  
  13.     if (dataSource == null) {  
  14.         dataSource = this.resolvedDefaultDataSource;  
  15.     }  
  16.     if (dataSource == null) {  
  17.         throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");  
  18.     }  
  19.     return dataSource;  
  20. }  

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

 

Java代码  收藏代码
  1. <bean id="onlineDynamicDataSource" class="com.xx.stat.base.dynamic.DynamicDataSource">  
  2.    <property name="targetDataSources">     
  3.       <map key-type="java.lang.String">     
  4.          <entry key="xx" value-ref="dataSourceXX"/>     
  5.          <entry key="yy" value-ref="dataSourceYY"/>     
  6.       </map>     
  7.    </property>     
  8.    <property name="defaultTargetDataSource" ref="dataSource"/>    
  9. </bean>  
 

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

 

Java代码  收藏代码
  1. public void afterPropertiesSet() {  
  2.     if (this.targetDataSources == null) {  
  3.         throw new IllegalArgumentException("targetDataSources is required");  
  4.     }  
  5.     this.resolvedDataSources = new HashMap(this.targetDataSources.size());  
  6.     for (Iterator it = this.targetDataSources.entrySet().iterator(); it.hasNext();) {  
  7.         Map.Entry entry = (Map.Entry) it.next();  
  8.         Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());  
  9.         DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());  
  10.         this.resolvedDataSources.put(lookupKey, dataSource);  
  11.     }  
  12.     if (this.defaultTargetDataSource != null) {  
  13.         this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);  
  14.     }  
  15. }  

 

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

Java代码  收藏代码
  1. public class DynamicDataSource extends AbstractRoutingDataSource{  
  2.       
  3.     @Override  
  4.     public void setTargetDataSources(Map targetDataSources) {  
  5.         super.setTargetDataSources(targetDataSources);  
  6.     }  
  7.       
  8.     @Override  
  9.     public Object unwrap(Class iface) throws SQLException {  
  10.         return null;  
  11.     }  
  12.   
  13.     @Override  
  14.     public boolean isWrapperFor(Class iface) throws SQLException {  
  15.         return false;  
  16.     }  
  17.   
  18.     @Override  
  19.     protected Object determineCurrentLookupKey() {  
  20.         String dataSourceName = DynamicDataSourceHolder.getDataSourceName();  
  21.         return dataSourceName;  
  22.     }  

 

DynamicDataSourceHolder

Java代码  收藏代码
  1. public class DynamicDataSourceHolder {  
  2.   
  3.     private static final ThreadLocal<String> holder = new ThreadLocal<String>();  
  4.       
  5.     public static void putDataSourceName(String name){  
  6.         holder.set(name);  
  7.     }  
  8.       
  9.     public static String getDataSourceName(){  
  10.         return holder.get();  
  11.     }  
  12. }  
 

 


相关文章推荐

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

在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSourc...

SSH框架(二) 利用AbstractRoutingDataSource实现动态数据源切换

在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSourc...

利用AbstractRoutingDataSource实现动态数据源切换 (Spring+Hibernate)

Spring配置多数据源的方式和具体使用过程 1、数据源的名称常量类     public enum DynamicDataSourceGlobal { Java...

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

最近要为公司多个游戏做类似的统计功能,考虑到模块的复用性,决定做个动态数据源,根据不同的游戏参数切换不同的datasource。 网上查了下,spring2.0以后增加了AbstractRout...

SpringMVC 使用jndi 多个数据源且利用AbstractRoutingDataSource实现动态数据源切换

配合上一章我们来进一步配置

Spring(AbstractRoutingDataSource)实现动态数据源切换

原始出处:http://linhongyu.blog.51cto.com/6373370/1615895 一、前言     近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好...

Spring(AbstractRoutingDataSource)实现动态数据源切换-- 转载

spring(AbstractRoutingDataSource)实现动态加载分布式数据库,配置多个数据源并实现动态切换!...

spring 使用AbstractRoutingDataSource自定义动态数据源时的事务处理问题

最近在网上看到了一篇博客,继承spring的AbstractRoutingDataSource

Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换

有时候需要在程序中动态切换数据源,那么这个系列的之前的博文所阐述的方法就不再使用了,总不能通过程序更改config.properties文件的dataSource的值,然后再重启web服务器以便加载a...

Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换

有时候需要在程序中动态切换数据源,那么这个系列的之前的博文所阐述的方法就不再使用了,总不能通过程序更改config.properties文件的dataSource的值,然后再重启web服务器以便加载a...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用AbstractRoutingDataSource实现动态数据源切换
举报原因:
原因补充:

(最多只允许输入30个字)