理解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 多数据源动态切换的更多相关文章

  1. Spring多数据源动态切换

    title: Spring多数据源动态切换 date: 2019-11-27 categories: Java Spring tags: 数据源 typora-root-url: ...... --- ...

  2. Spring主从数据源动态切换

    参考文档: http://uule.iteye.com/blog/2126533 http://lanjingling.github.io/2016/02/15/spring-aop-dynamicd ...

  3. Spring Boot 如何动态切换数据源

    本章是一个完整的 Spring Boot 动态数据源切换示例,例如主数据库使用 lionsea 从数据库 lionsea_slave1.lionsea_slave2.只需要在对应的代码上使用 Data ...

  4. 实战:Spring AOP实现多数据源动态切换

    需求背景 去年底,公司项目有一个需求中有个接口需要用到平台.算法.大数据等三个不同数据库的数据进行计算.组装以及最后的展示,当时这个需求是另一个老同事在做,我只是负责自己的部分. 直到今年回来了,这个 ...

  5. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  6. Springboot多数据源配置--数据源动态切换

    在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...

  7. springboot多数据源动态切换和自定义mybatis分页插件

    1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...

  8. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  9. mybatis 多数据源动态切换

    笔者主要从事c#开发,近期因为项目需要,搭建了一套spring-cloud微服务框架,集成了eureka服务注册中心. gateway网关过滤.admin服务监控.auth授权体系验证,集成了redi ...

随机推荐

  1. 多线程并发练习(Day35)

    练习一 #_*_coding:utf-8_*_ #!/usr/bin/env python import multiprocessing import threading import socket ...

  2. day4-迭代器、生成器yield

    一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...

  3. Codeforces Round #304 (Div.2)

    A. Soldier and Bananas 题意:有个士兵要买w个香蕉,香蕉起步价为k元/个,每多买一个则贵k元.问初始拥有n元的士兵需要借多少钱? 思路:简单题 #include<iostr ...

  4. s5_day7装饰器作业

    # 一:编写函数,(函数执行的时间是随机的) import time import random # def foo(): # time.sleep(random.randrange(1,5)) # ...

  5. Unity,如何阻塞当前函数一段时间

    public class Example : MonoBehaviour { IEnumerator Example() { print(Time.time); ); print(Time.time) ...

  6. lock关键字的用法

    一直以来对于lock关键字的用法都存有疑惑,也从网上看到很多关于他的资料包括MSDN,无奈MSDN讲述的真是让人上火.今天决定小小研究一下 一直都知道lock是锁定某一变量从而实现对某一代码段的独占执 ...

  7. Nginx 限制php解析、限制浏览器访问

    限制php解析 1.有时候会根据目录来限制php解析: location ~ .*(diy|template|attachments|forumdata|attachment|image)/.*\.p ...

  8. CreateWindow创建无边框 可拉伸窗体

    createwindow 定义 HWND WINAPI CreateWindow( _In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowNam ...

  9. linux 查看内存信息,及其他硬件信息 dmidecode命令

    由于想换内存,想看看内存型号.频率,简单搜了下命令 可以用dmidecode 命令查看. dmidecode -t memory 这个命令可以查看内存的几乎所有信息,包括频率 大小等等 另外这个命令强 ...

  10. ES6中Json、String、Map、Object之间的转换

    /** *字符串转json * */ static stringToJson(data){ return JSON.parse(data); } /** *json转字符串 */ static jso ...