1. AbstractRoutingDataSource
Spring提供了数据源切换抽线实现--AbstractRoutingDatasource类,通过继承该类可以实现动态数据源切换。
AbstractRoutingDataSource的多数据源动态切换的核心逻辑是:在程序运行时,通过spring的InitializingBean接口实现的afterPropertiesSet(),将数据源以key-value形式织入到内存中,然后通过AbstractRoutingDataSource实现的determineCurrentLookupKey()方法动态地获取数据源key,灵活的进行数据源切换。
实现逻辑:
- 把配置的多个数据源会放在AbstractRoutingDataSource的 targetDataSources(所有数据源)和defaultTargetDataSource(默认的数据源)中,然后通过afterPropertiesSet()方法将数据源分别进行复制到resolvedDataSources和resolvedDefaultDataSource中。
- 定义MultiDataSource类继承抽象类AbstractRoutingDataSource,并实现了determineCurrentLookupKey()方法,动态获取不同数据源的key(一般是通过ThreadLocal处理),为切换数据源做准备。
- 最后AbstractRoutingDataSource会根据内存的数据源信息以及动态key,动态地获取具体数据源,并且通过调用底层datasource.getConnection()方法从数据库连接池中获取某一个连接(具体Connection如何得到不用关心),有了连接和数据源后,datasource底层会自动实现sql的crud。
2.Multi-datasource框架多数据源切换实现逻辑
基于Spring的AbstractRoutingDataSource,我们只需要
- 将默认数据源以及所有需要动态切换的数据源添加到AbstractRoutingDataSource类的
defaultTargetDataSource以及targetDataSources,格式为Map<数据源key,数据源>
- 实现AbstractRoutingDataSource的determineCurrentLookupKey()方法,动态获取数据源key
由于事务切换肯定需要提供注解(定为@MS)做到业务隔离的,故需要借助AOP切面功能,所以底层框架实现伪代码如下:
①:从配置文件中读取所有数据源配置,并封装为具体数据源对象,添加到defaultTargetDataSource以及targetDataSources中.
源码如下:
@PostConstruct
public void init() {
setPrimary(multiDataSourceProperties.getPrimary());
// 添加并分组数据源
Map<String, DataSource> dataSources = new HashMap<>(16);
// 从配置文件中添加数据源(也提供了从其他地方添加数据源的抽象类)
for (MultiDataSourceProvider provider : providers) {
dataSources.putAll(provider.loadDataSources());
}
Map<Object, Object> targetDataSources = new HashMap<>(dataSources);
// 添加到dataSourceMap中
for (Map.Entry<String, DataSource> dsItem : dataSources.entrySet()) {
addDataSource(dsItem.getKey(), dsItem.getValue());
}
// 检测默认数据源是否设置
if (dataSourceMap.containsKey(primary)) {
log.info("dynamic-datasource initial loaded [{}] datasource,primary datasource named [{}]", dataSources.size(), primary);
} else {
log.warn("dynamic-datasource initial loaded [{}] datasource,Please add your primary datasource or check your configuration", dataSources.size());
}

最低0.47元/天 解锁文章
6508

被折叠的 条评论
为什么被折叠?



