• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

详解AbstractRoutingDataSource(动态数据源切换)实现原理

JAVA web前端中文站 2年前 (2017-09-27) 2861次浏览 已收录 0个评论

数据库读写分离,动态数据源切换已成为大型网站的标配。因此结合本文我们一起来搞定动态数据源切换的原理。

更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏

说到原理,就必须要说到源码,说到源码就必须要从我们最初的设计说起。

多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源。例如在一个 spring 和 hibernate 的框架的项目中,我们在 spring 配置中往往是配置一个 dataSource 来连接数据库,然后绑定给 sessionFactory,在 dao 层代码中再指定 sessionFactory 来进行数据库操作。

详解 AbstractRoutingDataSource(动态数据源切换)实现原理

上图是单数据源 dataSource 结构。但是上图的缺点太明显了,不支持多个数据源,于是我们再改进一下,让它支持多数据源。

详解 AbstractRoutingDataSource(动态数据源切换)实现原理

这种结构实现了多数据源,但是缺点也很明显啊,具有多个SessionFactory,不具有灵活性,而且太笨重了。如果再加一个数据源,就需要再加一个SessionFactory

SessionFactory接口负责初始化 Hibernate。它充当数据存储源的代理,并负责创建 Session 对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的。

顾名思义,SessionFactory,就是用来创建 session 会话(具体接下来讲)的工厂。如果存在多个 Sessionfactory 那么 Session 是不是就乱套了,因此这种架构不可取。那么下面这种架构就应用而生。

详解 AbstractRoutingDataSource(动态数据源切换)实现原理

看看上图,是不是感觉合理了很多。Spring 的 AbstractRoutingDataSource 就是采用这种架构。

看到这里你应该就明白了 AbstractRoutingDataSource 的原理。如果你还不明白,没关系,我们接着往下看。

看看?AbstractRoutingDataSource 的设计源码吧!

 public abstract class AbstractRoutingDataSource   
 extends AbstractDataSource   
 implements InitializingBean

扩展 Spring 的 AbstractRoutingDataSource 抽象类(该类充当了 DataSource 的路由中介, 能有在运行时, 根据某种 key 值来动态切换到真正的DataSource上。)

从上可以看出它继承了 AbstractDataSource,而 AbstractDataSource 不就是 javax.sql.DataSource 的子类吗,So 我们可以分析下它的 getConnection 方法:

 public Connection getConnection() throws SQLException {       
 return determineTargetDataSource().getConnection();   }   
 public Connection getConnection(String username, String password) 
 throws SQLException {        
 return determineTargetDataSource().getConnection(username, password);   }

获取连接的方法中,重点是 determineTargetDataSource()方法,看源码:

 protected DataSource determineTargetDataSource() {    
 Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");    
 Object lookupKey = determineCurrentLookupKey();    
 DataSource dataSource = this.resolvedDataSources.get(lookupKey);    
 if (dataSource == null && (this.lenientFallback || lookupKey == null)) {     
 dataSource = this.resolvedDefaultDataSource;    }    
 if (dataSource == null) {     
 throw new IllegalStateException("Cannot determine target DataSource for 
 lookup key [" + lookupKey + "]");    }    
 return dataSource;   }

上面这段源码的重点在于 determineCurrentLookupKey()方法,这是 AbstractRoutingDataSource 类中的一个抽象方法,而它的返回值是你所要用的数据源 dataSource 的 key 值,有了这个 key 值,resolvedDataSource(这是个 map,由配置文件中设置好后存入的)就从中取出对应的 DataSource,如果找不到,就用配置默认的数据源。

看完源码,应该有点启发了吧,没错!你要扩展 AbstractRoutingDataSource 类,并重写其中的 determineCurrentLookupKey()方法,来实现数据源的切换:

 package com.lisa33xiaoq.net.database; 
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 
 /**  * 获取数据源(依赖于 spring)  * @author linhy  */ 
 public class DynamicDataSource extends AbstractRoutingDataSource{     
 @Override  protected Object determineCurrentLookupKey() {         
 return DataSourceHolder.getDataSource();     } }

至此我相信关于 AbstractRoutingDataSource 的原理你已经明白了。现在在结合我们前面的一个案例来回顾一下 AbstractRoutingDataSource 吧。附上前一篇文章:Spring 动态路由 AbstractRoutingDataSource(数据源动态切换)教程。

本文原文出处:web 前端中文站: 详解 AbstractRoutingDataSource(动态数据源切换)实现原理

【注:本文源自网络文章资源,由站长整理发布】


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解 AbstractRoutingDataSource(动态数据源切换)实现原理
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址