目录:
- 原理
- 实现动态数据源
- 实战
- 问题
原理
看似复杂的东西都有一个极其简单的内核。在java中sql执行过程可以拆解为:
- 拿到 Datasource 对象;
- 打开链接 ds.getConnections();
- 执行sql
Spring实现动态数据源
如图所示:
- DynamicDataSource实现DataSource,注入spring容器中供使用;
- 这里面的逻辑 spring 做了支持,可以直接继承 AbstractRoutingDataSource 类即可;
- DataSourceManager
- 通过配置文件加载多个数据源
- 在线程中维护一个 Queue;
- 接口 use(datasourceId)接口,将新数据源标识(datasourceId)放入队列;
- 接口 over(),删除队列顶部数据;
- 接口 getDataSource(),返回队列顶部datasourceId 对应的数据源;
- DataSource注解,可以设置datasourceId值;
- DataSourceAspect ,切面;
- 对所有添加DataSource注解的方法设置切入点;
- 切入点执行前,更具DataSource的datasourceId 设置要使用的数据源;
- 切入点执行
- 切入点执行后,重置数据源(没有设置时不需要重置数据源);
实战
这里可以参考renren-security框架里的动态数据源实现,请移步:Renren框架Gitee地址
存在的问题
多数问题时因为无法进入切面、进而无法动设置数据源;事务是由于一旦开启事务、connection会被缓存在事务管理器里面,再执行sql时不会再通过Datasource获取链接,因此导致 无法切换数据源;
事务不能跨数据源
1 | //数据源不会切换 |
子类 不能向父类传递
1 | //数据源不会切换 |
接口不能向实现类传递
1 | //数据源不会切换 |