Spring实现动态数据源切换 包教包会

项目背景:
现在随着软件项目的越来越大、靠一个集中式的项目已经无法满足并发量。 如果说数据量特别大就需要进行分库。这是最基本的策略,比如按照省份分库、某几个省分为一个域。一个域对应一个物理数据库。
分域如下:
一域:北京、上海
二域:河南、宁夏
三域:山西、吉林
四域:广东、四川

===========================================================================
那我们项目中启一套程序怎么实现这种数据源的动态切换呢?

假设项目中已经实现了动态数据源切换?那我们总的有一个依据、省份编码就是一个很好的字段。根据请求中带来的:省份编码、IP信息、交易流水等都可以作为 切换数据源的依据。

思路上通了以后就看需要怎么样的技术才能实现数据源的切换呢?
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
里面有一个抽象方法
protected abstract Object determineCurrentLookupKey();

抽象方法就是自己只定义 不实现,让子类实现抽象方法赋值、然后返回到父类中。
//仔细看一下这个抽象方法返回的是个什么东西
protected DataSource determineTargetDataSource()
{
  Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
//抽象方法返回的 一个数据源的key 也就是Spring中注入数据源的一个Map集合的key
  Object lookupKey = determineCurrentLookupKey();
//根据key得到数据源 配置 Spring中注入数据源的一个Map集合的key 对应的value
  DataSource 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;
}


///////////////继续往下看这个dataSource返回给谁了////////////////////
AbstractRoutingDataSource 抽象类里面的方法
public Connection getConnection()throws SQLException
{
  return determineTargetDataSource().getConnection();
}
public Connection getConnection(String username, String password) throws SQLException {
  return determineTargetDataSource().getConnection(username, password);
}



//找到AbstractRoutingDataSource 的父类、父类里面没有这两个方法。
public abstract class AbstractRoutingDataSource extends AbstractDataSource

//父类AbstractDataSource  实现了一个DataSource接口
public abstract class AbstractDataSource  implements DataSource{
}

//在DataSource接口里面定义了这两个方法。
public interface DataSource  extends CommonDataSource,Wrapper {
Connection getConnection() throws SQLException;
Connection getConnection(String username, String password)
    throws SQLException;
}


AbstractRoutingDataSource实现了InitializingBean类,实现了afterPropertiesSet方法.afterPropertiesSet方法在bean的属性赋值之后执行,
并检查targetDataSources 是否有值,如果有值就将targetDataSources  转换成
resolvedDataSources.也就是说,如果你要使用AbstractRoutingDataSource,就必须在方法afterPropertiesSet执行之前,进行targetDataSources 属性的初始化.这也就是目前网上的配置方式,在配置文件里配置N个数据源的由来.
【扩展阅读 afterPropertiesSet 方法什么时候执行】
http://www.iteye.com/topic/1046993
===============================================

所有准备工作作为之后。写一个AOP的拦截到请求,解析请求中的省份编码。实现数据源切换。
整理一下代码。稍后会放到Git上 实现是Spring MVC + Mybatis环境。

猜你喜欢

转载自ican.iteye.com/blog/2256826