使用Adivisor配置增强处理,来实现数据库读写分离
一、先写一个demo来概述Adivisor的简单使用步骤
实现步骤:
1、通过MethodBeforeAdivice接口实现前置增强处理
public class ServiceBeforeAdvisor implements MethodBeforeAdvice {
private Logger logger = Logger.getLogger(ServiceBeforeAdvisor.class);
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
logger.info("启动事务");
logger.info("连接点对象:"+target.getClass().getSimpleName());
logger.info("连接点方法:"+method.getName());
logger.info("连接点方法参数:"+args[0]);
}
}
2、使用<aop:advisor>标签织入增强处理
//注意:advisor要放在aspect前面
<bean id="userService" class="com.pb.service.UserService"></bean>
<bean id="serviceBeforeAdvisor" class="com.pb.aop.ServiceBeforeAdvisor"></bean>
<aop:config>
<aop:pointcut expression="execution(public * com.pb.service.*.*(..))"
id="servicePointcut"/>
<aop:advisor advice-ref="serviceBeforeAdvisor" pointcut-ref="servicePointcut"/>
</aop:config>
3、测试类型
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
("applicationContext.xml");
UserService service = (UserService)context.getBean("userService");
service.addUser(new User());
}
}
二、使用Adivisor来实现数据读写分离
实现步骤:
1、通过MethodBeforeAdivice接口实现前置增强处理
public class DataBaseAdvice implements MethodBeforeAdvice {
/**
* 日志计数器
*/
private final static Logger logger = LoggerFactory.getLogger(DataBaseAdvice.class);
/**
* 存储方法前缀
*/
private List<String> methodKey;
/**
* 是否打印日志:true-打印,false-不打印
*/
private boolean showLog = true;
public void before(Method method, Object[] objects, Object o) throws Throwable {
boolean write = true;
String methodName = method.getName().toLowerCase();
//若方法前缀匹配成功,返回false
if (CollectionUtils.isNotEmpty(methodKey)) {
for (String key : methodKey) {
if (methodName.startsWith(key.toLowerCase())) {
write = false;
break;
}
}
}
if (write) {
DbContextHolder.setDbType(DbContextHolder.DB_TYPE_RW);
if (showLog) {
logger.info(method.getName()+"连接主库");
}
}else {
DbContextHolder.setDbType(DbContextHolder.DB_TYPE_R);
if (showLog) {
logger.info(method.getName()+"连接从库");
}
}
}
public List<String> getMethodKey() {
return methodKey;
}
public void setMethodKey(List<String> methodKey) {
this.methodKey = methodKey;
}
public boolean isShowLog() {
return showLog;
}
public void setShowLog(boolean showLog) {
this.showLog = showLog;
}
}
切换主从库的持有类
public class DbContextHolder {
/**
* 线程threadLocal
*/
private static ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* 主库:执行读写操作
*/
public static String DB_TYPE_RW = "dataSourceMaster";
/**
* 从库:执行读库操作
*/
public static String DB_TYPE_R = "dataSourceSlave";
/**
* 默认是读写库
* @return
*/
public static String getDbType() {
String db = contextHolder.get();
if (db == null) {
db = DB_TYPE_RW;
}
return db;
}
/**
* 置本线程的dbType
* @param str
*/
public static void setDbType(String str) {
contextHolder.set(str);
}
/**
* @Title: clearDBType
* @Description: 清理连接类型
*/
public static void clearDBType() {
contextHolder.remove();
}
}
2、使用<aop:advisor>标签织入增强处理
<!-- 动态数据源 -->
<bean id="dynamicDataSource" class="com.alibaba.health.dao.dynamic.DynamicDataSource">
<!-- 通过key-value关联数据源 -->
<property name="targetDataSources">
<map>
<entry value-ref="dataSourceMaster" key="monitorDataSourceMaster"/>
<entry value-ref="dataSourceSlave" key="monitorDataSourceSlave"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceMaster"/>
</bean> <!-- 通知器的具体实现:配置主从库读写分离:以select、query、find、count开头的方法走从库 -->
<bean id="DataBaseAdvice" class="com.aliaba.health.dao.dynamic.DataBaseAdvice">
<property name="methodKey">
<list>
<value>select</value>
<value>query</value>
<value>find</value>
<value>count</value>
</list>
</property>
<property name="showLog" value="false"/>
</bean> <!-- 切面配置 -->
<aop:config>
<!-- 配置切点:第一个*表示匹配所有方法的返回值类型,.表示当前包下所有类的方法,..表示当前包下及此包下所有自爆中的所有类方法;
第二个*表示所有类名,第三个*表示所有方法名,(..)表示所有方法参数-->
<aop:pointcut expression="execution(* com.alibaba.health.dao..*.*(..))" id="cutPoint"/>
<!-- 定义通知器 -->
<aop:advisor advice-ref="DataBaseAdvice" pointcut-ref="cutPoint"/>
</aop:config>
此时就完成了主从数据库读写分离的代码和xml配置,尤其可见各种技术组件,在于是否能灵活运用。
使用Adivisor配置增强处理,来实现数据库读写分离的更多相关文章
- yii2的数据库读写分离配置
简介 数据库读写分离是在网站遇到性能瓶颈的时候最先考虑优化的步骤,那么yii2是如何做数据库读写分离的呢?本节教程来给大家普及一下yii2的数据库读写分离配置. 两个服务器的数据同步是读写分离的前提条 ...
- 使用Adivisor配置增强处理
使用Adivisor配置增强处理 实现步骤: 1.通过MethodBeforeAdivice接口实现前置增强处理 public class ServiceBeforeAdvisor implement ...
- EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一
回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是sect ...
- centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课
centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数 ...
- Linux安装Mycat1.6.7.4并实现Mysql数据库读写分离简单配置
1. Mycat简介 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务.ACID.可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 一 ...
- Spring aop应用之实现数据库读写分离
Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果 ...
- CYQ.Data V5 数据库读写分离功能介绍
前言 好多年没写关于此框架的新功能的介绍了,这些年一直在默默地更新,从Nuget上的记录就可以看出来: 这几天在看Java的一些东西,除了觉的Java和.NET的相似度实在太高之外,就是Java太原始 ...
- 161220、使用Spring AOP实现MySQL数据库读写分离案例分析
一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...
- [转]Spring数据库读写分离
数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力. 主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在 ...
随机推荐
- Java调用Python相关问题:指定python环境、传入参数、返回结果
本篇文章涉及到的操作均在Windows系统下进行,Java调用python在原理上不难,但是可能在实际应用中会有各种各样的需求,网上其他的资料很不全,所以又总结了这篇文章,以供参考. 一.指定pyth ...
- 解决windows 1903 alt + tab 切换卡顿
右击此电脑图标 选择管理 服务和应用程序 服务 禁用system interface foundation service
- [Jenkins][GitHub]2 持续集成环境初探
预计阅读时间:30分钟 部署环境:Jenkins ver. 2.61 + Centos7 + Java 1.8 参考链接: http://www.jianshu.com/p/22b7860b4e81 ...
- jar命令详解
原文链接:https://www.cnblogs.com/anyehome/p/9435371.html JAR包是Java中所特有一种压缩文档,其实大家就可以把它理解为.zip包.当然也是有区别的, ...
- JDK环境变量配置linux
安装前先查看是否安装过jdk如果安装过则 卸载 1. 确定JDK的版本: rpm -qa | grep jdk rpm -qa | grep gcj 可能的结果是: libgcj-4.1.2-42.e ...
- Codeforces #503 C. Elections(贪心,逆向
我的参考的博客地址 题目 逆向考虑. 暴力遍历 k(k是1到n/2+1 范围内的),挑出对于每一个k,记对于党派 i,num[ i ]为其票数.num[ i ]小于k-1的就不用改变投票了(这部分是比 ...
- k8s的pod
一.Pod的分类 自主式Pod : 控制器管理的Pod:Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例.每个Pod都有一个特殊的被称为“根容器”的Pause容器. ...
- 胡搞-强化版的light oj-1055-的思路-AI版的6重暴力For循环的BFS
新题目大意: 三个棋子按照先后顺序,可以随意方向合法地走到空位置上(而不是像原题light oj-1055中的一样三个棋子每次走的方向都一致),当三个棋子全部走进目标地点,就结束:求需要指挥的最少次数 ...
- Robot Framework--RIDE面板与库的说明
Robot Framework的测试用例是以project作为单位进行管理的.一个project可以包含多个Test Suite文件,每一个Test Suite可以包含多条测试用例一个Test Sui ...
- python - Flask 基础(1)
这两天稍微接触了一点 Flask 框架,所以分享点基础 1. 配置文件 from flask import Flask app = Flask(__name__) # 使用自定义的配置文件 app.c ...