data-center项目中引用多数据源项目DynamicDataSourceContextHolder类添加数据源方法,如何生效的?

来源:8-15 【单元测试】表达式引擎及存储器集成单元测试

崛起的架构师

2023-09-28

老师您好,我对data-center项目中引用多数据源项目DynamicDataSourceContextHolder.addDataSource()方法,怎么做到多数据源的不太理解,希望您能给讲讲,多谢。
DynamicJdbcRepository类

// 返回自定义的bean集合,参数传入map
public <T> List<T> listBeans(String sql, String dataSource, Class<T> resultType, Map<String, Object> args) {
    DynamicDataSourceContextHolder.addDataSource(dataSource);
    List<T> beanList = jdbcTemplate.query(sql, args, new DataClassRowMapper(resultType));
    DynamicDataSourceContextHolder.removeCurrentDataSource();
    return beanList;
}

其中:DynamicDataSourceContextHolder.addDataSource(dataSource);执行后,jdbcTemplate.query怎么就获取到添加的数据源的?

写回答

1回答

Tim老师

2023-09-28

同学你好,首先我们理解源码从宏观层面理解,有助于加深并且记住原理。然后再从微观上面扣细节,这个效果会比较好。

从宏观层面,jdbcTemplate.query怎么就获取到了添加的数据源呢?首先这个问题很简单,因为jdbcTemplate被springboot自动装配了,即JdbcTemplateConfiguration,创建jdbcTemplate自动就会将spring存在的datasource自动赋值。而我们之前配置了一个datasource给spring,并且优先级是primary,也就是DynamicRoutingDataSource,那么自然,这个datasource不就给到jdbcTemplate了吗?

宏观层面理解之后,就是扣细节了,那么为啥是DynamicDataSourceContextHolder.addDataSource(dataSource);要先执行,意义在哪里呢? 执行这行代码的逻辑就是将当前datasource给到DynamicDataSourceContextHolder的一个本地变量threadlocal的双端队列,那么目的在哪里呢?当jdbcTemplate需要执行sql的时候,因为之前已经拿到了一个我们准备好的DynamicRoutingDataSource,这个时候当然是调用datasource的getConnection方法了,那么具体的datasource是什么呢?还是我们之前准备好的DynamicRoutingDataSource,那么当然会调用他的父类的AbstractRoutingDataSource的getConnection方法了,这个时候具体要获取哪一个数据源,其实还是依赖我们之前写的DynamicDataSourceContextHolder的threadlocal的双端队列里面的数据源了,所以整体就串起来了!

同学如果还不理解,先从宏观层面理解,宏观层面其实不依赖我们的实现,宏观层面里面之后,然后就是整个流程串起来了。最后微观这里理解如果还有困难可以再结合视频回顾一下



0
2
Tim老师
回复
崛起的架构师
没事,一起加油啊
2023-09-28
共2条回复

SpringBoot3.0 + RocketMq 构建企业级数据中台

SpringBoot3.0 + RocketMq 构建企业级数据中台

214 学习 · 64 问题

查看课程