基于AbstractRoutingDataSource实现动态切换数据源
基于AbstractRoutingDataSource实现动态切换数据源
/**
* DataSource注解接口
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface
DataSourceAnnotation {
String value() default DataSourceSelect.MASTER;
}
/**
* 注解前后增强获取数据库清空数据库
*/
@Aspect
@Component
@Logger
public class DatasourceAspect {
@Pointcut("@annotation(com.example.demo.config.DataSourceAnnotation)")
public void pointcut() {
}
@Before("pointcut()")
public void beforeExecute(JoinPoint
joinPoint) {
Method method =
((MethodSignature) joinPoint.getSignature()).getMethod();
DataSourceAnnotation annotation = method.getAnnotation(DataSourceAnnotation.class);
if (annotation == null) {
annotation =
joinPoint.getTarget().getClass().getAnnotation(DataSourceAnnotation.class);
DynamicDataSource.setDataSource(DataSourceSelect.MASTER);
}else{
// 切换数据源
DynamicDataSource.setDataSource (annotation.value());
}
}
@After("pointcut()")
public void afterExecute() {
DynamicDataSource.clear();
}
}
定义数据源类来存储多个数据源选择
public interface DataSourceSelect {
/**
* 主库源
*/
String MASTER="master";
/**
* 从库源
*/
String SLAVE ="slave";
}
继承AbstractRoutingDataSource重写方法实现把默认数据源和目标数据源注入
并提供ThreadLocal线程保证数据源隔离。
public class DynamicDataSource extends AbstractRoutingDataSource
{
private final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
private static final ThreadLocal<String> DATA_SOURCE_CONTEXT_HOLDER = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object
determineCurrentLookupKey() {
return getDataSource();
}
static void setDataSource(String
dataSource) {
DATA_SOURCE_CONTEXT_HOLDER.set(dataSource);
}
public static String getDataSource() {
return DATA_SOURCE_CONTEXT_HOLDER.get();
}
static void clear() {
DATA_SOURCE_CONTEXT_HOLDER.remove();
}
}
把数据源配置路径与数据源匹配,并利用子类调用有参构造调用父类AbstractRoutingDataSource的方法把数据源信息加载进datasource
/**
* 配置多数据源
* @author xiaohe
* @version V1.0.0
*/
@Configuration
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.master")
public DataSource
masterDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.slave")
public DataSource
slaveDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource
dataSource(DataSource masterDataSource, DataSource
slaveDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>(5);
targetDataSources.put(DataSourceSelect.MASTER, masterDataSource);
targetDataSources.put(DataSourceSelect.SLAVE, slaveDataSource);
return new DynamicDataSource(masterDataSource, targetDataSources);
}
}
Application启动项,exclude = DataSourceAutoConfiguration.class排除自动注入数据源的配置,加上Import 用来加加载我们定义的datasource。
@ComponentScan(basePackages ="com.example.demo.*")
@EnableJpaRepositories("com.example.demo.repository")
@Import(DynamicDataSourceConfig.class)
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DruidApplication {
public static void main(String[] args) {
SpringApplication.run(DruidApplication.class, args);
}
}
FQA:
9. 注解没有被注入到ioc容器导致注解失效。
10. 多数据源的动态切换,在程序运行时,把数据源数据源动态织入到程序中,灵活的进行数据源切换。
- 基于多数据源的动态切换,我们可以实现读写分离,这么做缺点也很明显,无法动态的增加数据源。
只支持单库事务,也就是说切换数据源要在开启事务之前执行。
spring DataSourceTransactionManager进行事务管理,开启事务,会将数据源缓存到DataSourceTransactionObject对象中进行后续的commit rollback等事务操作。
基于AbstractRoutingDataSource实现动态切换数据源的更多相关文章
- AbstractRoutingDataSource 实现动态切换数据源
扩展AbstractRoutingDataSource类 package com.datasource.test.util.database; import org.springframework.j ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- hibernate动态切换数据源
起因: 公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还 ...
- 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法
相关项目地址:https://github.com/helloworlde/SpringBoot-DynamicDataSource 1. org.apache.ibatis.binding.Bind ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- Spring+Mybatis动态切换数据源
功能需求是公司要做一个大的运营平台: 1.运营平台有自身的数据库,维护用户.角色.菜单.部分以及权限等基本功能. 2.运营平台还需要提供其他不同服务(服务A,服务B)的后台运营,服务A.服务B的数据库 ...
- Spring动态切换数据源及事务
前段时间花了几天来解决公司框架ssm上事务问题.如果不动态切换数据源话,直接使用spring的事务配置,是完全没有问题的.由于框架用于各个项目的快速搭建,少去配置各个数据源配置xml文件等.采用了动态 ...
- AOP获取方法注解实现动态切换数据源
AOP获取方法注解实现动态切换数据源(以下方式尚未经过测试,仅提供思路) ------ 自定义一个用于切换数据源的注解: package com.xxx.annotation; import org. ...
随机推荐
- ssh免密码登录与常见问题
免密码登录 cd ~/.ssh ssh-keygen -t rsa #然后敲回车 mv id_rsa.pub master_rsa.pub cat master_rsa.pub >> au ...
- 开启php的PDO扩展,mysql扩展
打开php.ini配置文件,找到extension=php_pdo.dll 和 extension=php_pdo_mysql.dll ,去掉前面“;”的注释,修改后的两行配置内容如下: extens ...
- d3.js之树形折叠树
1.效果 children和_children 2.技术分解 2.1折叠函数 // (1) 递归调用,有子孙的就把children(显示)给_children(不显示)暂存,便于折叠, functio ...
- 报错:Table 'sell.hibernate_sequence' doesn't exist
错误信息:Table 'sell.hibernate_sequence' doesn't exist 错误原因:实体主键没有配置主键自增长 完整配置如下 /**主键id*/ @Id @Generate ...
- C++ STL介绍——简介
目录 1.什么是STL 2.STL中六大组件 2.1 容器(Container) 2.2 迭代器(Iterator) 2.3 算法(Algorithm) 2.4 仿函数(Functor) 2.5 适配 ...
- CentOS 修改固定IP地址
CentOS 修改固定IP地址 参考地址:https://www.cnblogs.com/technology-huangyan/p/9146699.htmlhttps://blog.csdn.net ...
- 设计自用的golang日志模块
设计自用的golang日志模块 golang的原生日志模块不能满足需求,而开源的第三方包,也不完全够用.用户较多的logrus,却没有rotate功能,这已经是众所周知的.对于运维来说,当然是希望日志 ...
- 性能监控 | MAT分析内存泄漏
使用MAT分析内存泄漏(二)八周年重印版 - 知乎 .u-safeAreaInset-top { height: constant(safe-area-inset-top) !important; h ...
- Hibernate 自动更新表出错 More than one table found in namespace
报错:Caused by: org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table f ...
- SpringCloud学习成长之路七 高可用配置中心
上一篇文章讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如 ...