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 ...
随机推荐
- Tomcat的session
创建session 在具体说明session的创建过程之前,先看一下BS访问模型: browser发送Http request: tomcat内核Http11Processor会从HTTP requ ...
- day3-python的函数及参数
函数式编程最重要的是增强代码的重用性和可读性 1 2 3 4 def 函数名(参数): ... 函数体 ... 函数的定义主要有如下要点: def:表示函数的关键字 函数名:函 ...
- Python(面向对象编程—1)
class tst: l=[] x=1 a=tst() b=tst() a.l.append('a') b.l.append('b') a.x='a' b.x='b' print(a.l,a.x) # ...
- hadoop28---注解
spring.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="ht ...
- C++添加简单的日记记录
#include<fstream>#include<iostream> using namespace std;//这是一种日记记录 b 种void LOG(char *tx, ...
- 【leetcode刷题笔记】Find Minimum in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- Cookie应用参考
内容来自imooc.
- 微服务与SOA
微服务跟SOA有什么区别呢,可以把微服务当做去除了ESB的SOA.ESB是SOA架构中的中心总线,拓扑结构应该是星形的,而微服务是去中心化的分布式软件架构. 一.巨石(monolith) web应用程 ...
- jQuery多层级垂直手风琴菜单
在线演示 本地下载
- shell编程学习笔记--整数自增
在Shell脚本中,用于while或for循环中经常要涉及到整数自增的情况,下面罗列下可能的方式 [方式一]declare -i来声明整数变量 root@localhost:~# declare -i ...