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 ...
随机推荐
- 自定义ActionBar图标
<style name="Theme.glTheme" parent="android:Theme.Holo"> <item name=&qu ...
- Linux学习笔记(5)磁盘分区(parted)
Linux学习笔记(5)磁盘分区(parted) .演示: ()parted /dev/sdb :进入parted 分区命令(可以使用help来查看命令详细描述)(2)p :列出当前磁盘分区信息,可以 ...
- 003-主流区块链技术特点及Hyperledger Fabric V1.0版本特点
一.Hyperledger fabric V1.0 架构 1.逻辑架构: 2.区块链网络 3.运行时架构 二.架构总结 1.架构要点 分拆Peer的功能,将Blockchain的数据维护和共识服务进行 ...
- SqlServer分页总结-摘抄
sqlserver2008不支持关键字limit ,所以它的分页sql查询语句将不能用mysql的方式进行,幸好sqlserver2008提供了top,rownumber等关键字,这样就能通过这几个关 ...
- Levenshtein距离
Levenshtein Distance,又称Edit Distance,在自然语言处理中有着广泛的应用.Levenshtein Distance 指的是两个字符串之间,由一个转换成另一个所需的最少 ...
- Mahout 分类算法
实验简介 本次课程学习了Mahout 的 Bayes 分类算法. 一.实验环境说明 1. 环境登录 无需密码自动登录,系统用户名 shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu ...
- Git服务器的Gitosis安装配置及gitignore的使用方法
Git服务器Gitosis安装设置 1.安装 openssh服务器 sudo apt-get install openssh-server openssh-client 2.创建个人公钥和私钥 在默认 ...
- JAVA基础补漏--继承
子类的对象在创建时,首先调用父类的构造函数,再调用子类自己的构造函数. 子类的构造函数中,有一个默认的super(),为一个无参调用,这个不显示,但会被首先调用,所有才会有父类构造函数被调用的情况. ...
- Spring Boot 设置启动时banner
Spring Boot项目再启动的时候默认会在控制台输出一个字符banner图案,如下图: 我们可以通过下面的方法关闭启动时显示字符banner图案: 关闭banner方法一: public stat ...
- spring security使用hibernate进行查询数据库验证
前面查询数据库采用的都是jdbc方式,如果系统使用的是hibernate,该如何进行呢,下面就是实现步骤,关键还是实现自定义的UserDetailsService 项目结构如下: 使用hibernat ...