spring 多数据源动态切换
理解spring动态切换数据源,需要对spring具有一定的了解
工作中经常遇到读写分离,数据源切换的问题,那么以下是本作者实际工作中编写的代码 与大家分享一下!
1.定义注解 DataSource
package com.gomecar.index.datasource; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 数据源切换注解
* @author xiaotian
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface DataSource { String value() default "read"; }
2. 定义切面DataSourceAspect
package com.gomecar.index.datasource; import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature; /**
* 用于数据库读写分离的切面
* @author xiaotian
*
*/
@Aspect
public class DataSourceAspect { //日志
private Logger logger = Logger.getLogger(this.getClass()); /**
* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
} /**
* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解dataSourcePointcutdataSourcePointcut
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.putDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.putDataSource(source.value());
}
} catch (Exception e) {
logger.error("切换数据源error", e);
}
} //通知
public void before(JoinPoint point)
{
Object target = point.getTarget();
String method = point.getSignature().getName();
//反射获取接口
Class<?>[] classz = target.getClass().getInterfaces();
//获取返回值类型
Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())
.getMethod().getParameterTypes();
try {
//获取方法
Method m = classz[0].getMethod(method, parameterTypes);
//根据方法上注解 获取只读数据库连接池 或者只写数据库连接池
if (m != null && m.isAnnotationPresent(DataSource.class)) {
//根据注解值获取数据库连接池
DataSource data = m
.getAnnotation(DataSource.class);
DynamicDataSourceHolder.putDataSource(data.value());
System.out.println(data.value());
} } catch (Exception e) {
// TODO: handle exception
}
}
}
3.获取动态数据源DynamicDataSource
package com.gomecar.index.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态获取数据源
* @author xiaotian
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource { @Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDataSouce();
} }
4.数据源持有者DynamicDataSourceHolder
package com.gomecar.index.datasource;
/**
* 数据库连接池 持有者
* 将数据库连接绑定到当前线程
* @author xiaotian
*
*/
public class DynamicDataSourceHolder {
//绑定当前线程
public static final ThreadLocal<String> holder = new ThreadLocal<String>();
//设置数据源
public static void putDataSource(String name) {
holder.set(name);
}
//获取数据源
public static String getDataSouce() {
return holder.get();
}
}
spring 多数据源动态切换的更多相关文章
- Spring多数据源动态切换
title: Spring多数据源动态切换 date: 2019-11-27 categories: Java Spring tags: 数据源 typora-root-url: ...... --- ...
- Spring主从数据源动态切换
参考文档: http://uule.iteye.com/blog/2126533 http://lanjingling.github.io/2016/02/15/spring-aop-dynamicd ...
- Spring Boot 如何动态切换数据源
本章是一个完整的 Spring Boot 动态数据源切换示例,例如主数据库使用 lionsea 从数据库 lionsea_slave1.lionsea_slave2.只需要在对应的代码上使用 Data ...
- 实战:Spring AOP实现多数据源动态切换
需求背景 去年底,公司项目有一个需求中有个接口需要用到平台.算法.大数据等三个不同数据库的数据进行计算.组装以及最后的展示,当时这个需求是另一个老同事在做,我只是负责自己的部分. 直到今年回来了,这个 ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Springboot多数据源配置--数据源动态切换
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...
- springboot多数据源动态切换和自定义mybatis分页插件
1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- mybatis 多数据源动态切换
笔者主要从事c#开发,近期因为项目需要,搭建了一套spring-cloud微服务框架,集成了eureka服务注册中心. gateway网关过滤.admin服务监控.auth授权体系验证,集成了redi ...
随机推荐
- 005-shiro认证
一.shiro认证流程 二.入门程序 1.代码: 2.配置shiro-first.ini 通过此配置文件创建securityManager工厂. 需要修改eclipse的ini的编辑器: 配置数据: ...
- corethink功能模块探索开发(十四)后台编辑按钮
效果图: 1.添加下图55&58行代码 2.实现edit方法 位于Equip/Admin/DeviceRepaireAdmin.class.php中 public function edit( ...
- python学习之路-第八天-文件IO、储存器模块
文件IO.储存器模块 文件IO 代码示例: # -*- coding:utf-8 -*- #! /usr/bin/python # filename:using_file.py poem = '''\ ...
- Ubuntu14.04安装QT5.5
1.进入qt目录下,修改qt安装文件属性 2:执行./qt-opensource-linux-xXXX; 3.启动Qt Creater:进入Qt5./Tools/QtCreater/bin/,可以鼠标 ...
- Python(迭代、三元表达式、列表生成、生成器、迭代器)
迭代 什么是迭代 1 重复 2 下次重复一定是基于上一次的结果而来 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). ...
- JavaScript 函数,math对象,Date对象 序列化 总结
函数 函数定义 // 普通函数定义 function f1() { console.log("Hello world!"); } // 带参数的函数 function f2(a, ...
- 我们为什么使用ORM
我们为什么使用ORM? http://www.cnblogs.com/tansm/archive/2006/06/07/419927.html 博客园在推广ORM方面的确做了很大的贡献,很多的程序员开 ...
- html基本标签介绍及应用
<!-- html标签 特征: 1.空白折叠现象 2.对空格和换行不敏感 3.标签要严格封闭 p标签的嵌套 多注意!!!!!! html中: 1.行内标签(不换行) (1)在一行内显示 span ...
- Linux信号signal处理机制
信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 ...
- hadoop08---读写锁
ReentrantLock 直接使用lock接口的话,我们需要实现很多方法,不太方便,ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法,Reen ...