一、先写一个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配置增强处理,来实现数据库读写分离的更多相关文章

  1. yii2的数据库读写分离配置

    简介 数据库读写分离是在网站遇到性能瓶颈的时候最先考虑优化的步骤,那么yii2是如何做数据库读写分离的呢?本节教程来给大家普及一下yii2的数据库读写分离配置. 两个服务器的数据同步是读写分离的前提条 ...

  2. 使用Adivisor配置增强处理

    使用Adivisor配置增强处理 实现步骤: 1.通过MethodBeforeAdivice接口实现前置增强处理 public class ServiceBeforeAdvisor implement ...

  3. EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一

    回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是sect ...

  4. centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课

    centos  MySQL主从配置 ntsysv   chkconfig  setup命令  配置MySQL 主从 子shell  MySQL备份  kill命令  pid文件  discuz!论坛数 ...

  5. Linux安装Mycat1.6.7.4并实现Mysql数据库读写分离简单配置

    1. Mycat简介 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务.ACID.可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 一 ...

  6. Spring aop应用之实现数据库读写分离

    Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果 ...

  7. CYQ.Data V5 数据库读写分离功能介绍

    前言 好多年没写关于此框架的新功能的介绍了,这些年一直在默默地更新,从Nuget上的记录就可以看出来: 这几天在看Java的一些东西,除了觉的Java和.NET的相似度实在太高之外,就是Java太原始 ...

  8. 161220、使用Spring AOP实现MySQL数据库读写分离案例分析

    一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...

  9. [转]Spring数据库读写分离

    数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力. 主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在 ...

随机推荐

  1. Ipython 和 python 的区别

    IPython是一个python交互shell,它比默认的python shell更易于使用.它支持自动变量完成.自动缩进.bash shell命令,并且内置了许多有用的函数和函数. IPython是 ...

  2. sql server 2012 分页/dapper/C#拼sql/免储存过程/简易

    sql server 2012新特性, 支持 OFFSET/FETCH分页, 就像mysql的limit, 比之前的各种top舒服多了,  看各位大佬们的测评文章说效率也是不相上下的, 有时候写个小工 ...

  3. 如何:确定已安装的 .NET Framework 版本

    用户可在他们的计算机上安装和运行 .NET Framework 的多个版本. 当你开发或部署应用时,你可能需要知道用户的计算机上安装了哪些 .NET Framework 版本. .NET Framew ...

  4. Redis系列之-—内存淘汰策略(笔记)

    一.Redis ---获取设置的Redis能使用的最大内存大小 []> config get maxmemory ) "maxmemory" ) " --获取当前内 ...

  5. Windows Server 2016 IIS的安装与配置

    1. 打开服务器管理器,点击[添加角色和功能选项].        2. 进入“添加角色和功能向导”页面,点击下一步. 3. 安装类型选择[基于角色或基于功能的安装],点击下一步. 4. 进入服务器选 ...

  6. 十年种树----小白的起点save

    大家好,给大家介绍一下我自己.各平台通用ID:琴鬼白羊,男,一个24岁学习采矿工程的在读研究僧,一个24岁还在想学习计算机的小白. 非洲经济学家Dambisa Moyo在他的<dead aid& ...

  7. Codeforces #364 (Div. 2) D. As Fa(数学公式推导 或者二分)

    数学推导的博客 http://codeforces.com/contest/701/problem/D  题目 推导的思路就是 : 让每个人乘车的时间相等 ,让每个人走路的时间相等. 在图上可以这么表 ...

  8. python中部分数据类型及其使用方法

    1.数据类型: int:整数 str:字符串,一般不存放大量的数据 bool:布尔值,用来判断 只有两个值 True False  list:列表,用来存放大量数据[]来表示,里面可以放任何数据类型 ...

  9. 0018SpringBoot连接docker中的mysql并使用druid数据源

    由于druid数据源自带监控功能,所以引用druid数据源 1.centos7中安装并启动docker 2.docker安装并启动mysql 3.pom.xml中引入druid依赖 4.applica ...

  10. DNS工作流程及原理 域名、IP与DNS的关系

    转自:http://blog.csdn.net/maminyao/article/details/7390208 一.DNS服务概述 DNS是Domain Name System的缩写,即域名系统.其 ...