MultiDatasource源码解析

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());

        }

   
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值