一、先写一个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. ios数组倒序

    比如有一个数组: NSArray *arr = @["]; 倒过来排序: arr = [[arr reverseObjectEnumerator] allObjects]; NSMutabl ...

  2. linux命令管道符

    linux多命令 ; 多个命令互相不影响 a && b  a命令执行成功才执行b命令 a || b a成功不执行b  a失败执行b ifconfig && echo & ...

  3. 【SpringMVC】参数绑定

    一.概述 1.3 参数绑定过程 1.2 @RequestParam 二.自定义绑定使用属性编辑器 2.1 使用WebDataBinder(了解) 2.2 使用WebBindingInitializer ...

  4. javascript_13-函数是一种数据类型

    函数是一种数据类型 函数是一种数据类型 function var num =60; // 1 函数是一种数据类型 function var myFun = function(){ console.lo ...

  5. 如何在windows server2016搭建DHCP服务器

    DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议.指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分 ...

  6. Notes for <<Thinking In Java>>

    String   Thus, when you create a toString( ) method, if the operations are simple ones that the comp ...

  7. Linux CPU问题排查

    某个进程的内存占用情况 查找进程pid——>进入该进程的目录/proc/{pid}/.有三个文件记录了进程内存 root@ROUTER:~# ps | grep zebra 1507 root ...

  8. Spring Boot起步依赖:定制starter

    在定制我们自己的起步依赖--xxx.spring.boot.starter之前,我们先了解下什么是Spring Boot起步依赖. 起步依赖,是Spring Boot带给我们的一项重要的便利.要理解S ...

  9. 设计模式之命令模式-JS

    理解命令模式 假设有一个快餐店,而我是该餐厅的点餐服务员,那么我一天的工作应该是这样的:当某位客人点餐或者打来订餐电话后,我会把他的需求都写在清单上,然后交给厨房,客人不用关心是哪些厨师帮他炒菜.我们 ...

  10. 用CSS 实现 非浮动元素的 水平居中/垂直居中/水平垂直居中

    一.水平居中 (1)行内元素解决方案 只需要把行内元素包裹在一个属性display为block的父层元素中,并且把父层元素添加如下属性即可:   .parent { text-align:center ...