Spring 动态数据源路由-源码分析
来源:互联网 发布:西安手机定位软件 编辑:程序博客网 时间:2024/04/29 08:26
本文基于Spring 4.1.6 RELEASE源码 进行分析。
先看看之前咱们在spring-mybatis.xml文件中配置的动态数据源,如下:
<bean id="dataSource" class="com.ricky.codelab.spring.ds.DynamicRoutingDataSource"> <property name="targetDataSources"> <map key-type="com.ricky.codelab.spring.ds.RouteStrategy"> <entry key="slave1" value-ref="slave1DataSource"/> <entry key="slave2" value-ref="slave2DataSource"/> </map> </property> <!-- 默认目标数据源为主库数据源 --> <property name="defaultTargetDataSource" ref="masterDataSource"/></bean>
DynamicRoutingDataSource 继承自AbstractRoutingDataSource 类,代码如下:
package com.ricky.codelab.spring.ds;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/** * 动态数据源切换 * * @author Ricky Fung * @create 2016-10-18 22:41 */public class DynamicRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DynamicRoutingContextHolder.getRouteStrategy(); }}
AbstractRoutingDataSource 类的定义,源码如下:
package org.springframework.jdbc.datasource.lookup;public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { private Map<Object, Object> targetDataSources; private Object defaultTargetDataSource; private boolean lenientFallback = true; private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); private Map<Object, DataSource> resolvedDataSources; private DataSource resolvedDefaultDataSource;}
AbstractRoutingDataSource 实现了InitializingBean接口,Spring容器启动时会回调其afterPropertiesSet()方法,AbstractRoutingDataSource afterPropertiesSet()如下:
public void afterPropertiesSet() { if(this.targetDataSources == null) { throw new IllegalArgumentException("Property \'targetDataSources\' is required"); } else { this.resolvedDataSources = new HashMap(this.targetDataSources.size()); Iterator var1 = this.targetDataSources.entrySet().iterator(); while(var1.hasNext()) { Entry entry = (Entry)var1.next(); Object lookupKey = this.resolveSpecifiedLookupKey(entry.getKey()); DataSource dataSource = this.resolveSpecifiedDataSource(entry.getValue()); this.resolvedDataSources.put(lookupKey, dataSource); } if(this.defaultTargetDataSource != null) { this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource); } }}protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException { if(dataSource instanceof DataSource) { return (DataSource)dataSource; } else if(dataSource instanceof String) { return this.dataSourceLookup.getDataSource((String)dataSource); } else { throw new IllegalArgumentException("Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource); }}
这里主要把在xml中配置的targetDataSources解析到resolvedDataSources,defaultTargetDataSource 赋值到resolvedDefaultDataSource 。
另外,AbstractRoutingDataSource 继承自AbstractDataSource,而AbstractDataSource 是DataSource的一个子类,如下:
package org.springframework.jdbc.datasource;public abstract class AbstractDataSource implements DataSource { protected final Log logger = LogFactory.getLog(this.getClass()); public AbstractDataSource() { }}
因此,我们只需要看AbstractRoutingDataSource 的getConnection()方法实现即可,如下:
public Connection getConnection() throws SQLException { return this.determineTargetDataSource().getConnection();}public Connection getConnection(String username, String password) throws SQLException { return this.determineTargetDataSource().getConnection(username, password);}
determineTargetDataSource()方法如下:
protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); Object lookupKey = this.determineCurrentLookupKey(); 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 + "]"); } else { return dataSource; }}
determineTargetDataSource方法决定返回哪个DataSource 对象,它根据determineCurrentLookupKey方法(这个方法正是我们在DynamicRoutingDataSource类中重写的方法)获取数据源的key,然后从 resolvedDataSources中根据key取出DataSource ,如果返回的DataSource 为空,则使用默认的DataSource。
- Spring 动态数据源路由-源码分析
- Spring动态数据源路由实现
- Spring动态数据源路由实现
- Spring 动态数据源路由(Dynamic DataSource Routing)
- Spring动态切换数据源
- spring动态数据源1
- SPRING动态数据源使用方法
- spring 动态数据源切换
- Spring动态数据源
- spring mvc 动态数据源
- spring 动态注册数据源
- spring 动态数据源不起作用
- spring配置动态数据源
- Spring 动态数据源配置
- spring动态加载数据源
- spring动态切换数据源
- spring动态切换数据源
- spring动态数据源
- Maven依赖排除 禁止依赖传递 取消依赖的方法
- 数据库SQL的基本操作
- C语言学习--指针认识
- java文件压缩
- Ubuntu 16.04 Java8环境安装
- Spring 动态数据源路由-源码分析
- 51nod 1014 X^2 Mod P
- C++ string 分割字符串
- nexus的安装与配置
- 计算耗子数量
- 基于TCP的服务端/客户端
- 走进设计模式(三)-行为型模式(上)
- socket网络编程
- 通讯录 之 快速索引