使用Adivisor配置增强处理,来实现数据库读写分离

一、先写一个demo来概述Adivisor的简单使用步骤

实现步骤:

1、通过MethodBeforeAdivice接口实现前置增强处理

 1 public class ServiceBeforeAdvisor implements MethodBeforeAdvice {
 2     private Logger logger = Logger.getLogger(ServiceBeforeAdvisor.class);
 3     @Override
 4     public void before(Method method, Object[] args, Object target)
 5             throws Throwable {
 6         logger.info("启动事务");
 7         logger.info("连接点对象:"+target.getClass().getSimpleName());
 8         logger.info("连接点方法:"+method.getName());
 9         logger.info("连接点方法参数:"+args[0]);
10
11     }
12
13 }

2、使用<aop:advisor>标签织入增强处理

1 //注意:advisor要放在aspect前面
2     <bean id="userService" class="com.pb.service.UserService"></bean>
3      <bean id="serviceBeforeAdvisor" class="com.pb.aop.ServiceBeforeAdvisor"></bean>
4      <aop:config>
5          <aop:pointcut expression="execution(public * com.pb.service.*.*(..))"
6                 id="servicePointcut"/>
7          <aop:advisor advice-ref="serviceBeforeAdvisor" pointcut-ref="servicePointcut"/>
8      </aop:config>

3、测试类型

1 public class Test {
2     public static void main(String[] args) {
3         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
4                     ("applicationContext.xml");
5         UserService service =  (UserService)context.getBean("userService");
6         service.addUser(new User());
7     }
8 }

二、使用Adivisor来实现数据读写分离

实现步骤:

1、通过MethodBeforeAdivice接口实现前置增强处理

 1 public class DataBaseAdvice implements MethodBeforeAdvice {
 2     /**
 3      * 日志计数器
 4      */
 5     private final static Logger logger = LoggerFactory.getLogger(DataBaseAdvice.class);
 6     /**
 7      * 存储方法前缀
 8      */
 9     private List<String> methodKey;
10     /**
11      * 是否打印日志:true-打印,false-不打印
12      */
13     private boolean showLog = true;
14
15     public void before(Method method, Object[] objects, Object o) throws Throwable {
16         boolean write = true;
17         String methodName = method.getName().toLowerCase();
18         //若方法前缀匹配成功,返回false
19         if (CollectionUtils.isNotEmpty(methodKey)) {
20             for (String key : methodKey) {
21                 if (methodName.startsWith(key.toLowerCase())) {
22                     write = false;
23                     break;
24                 }
25             }
26         }
27
28         if (write) {
29             DbContextHolder.setDbType(DbContextHolder.DB_TYPE_RW);
30             if (showLog) {
31                 logger.info(method.getName()+"连接主库");
32             }
33         }else {
34             DbContextHolder.setDbType(DbContextHolder.DB_TYPE_R);
35             if (showLog) {
36                 logger.info(method.getName()+"连接从库");
37             }
38         }
39     }
40
41     public List<String> getMethodKey() {
42         return methodKey;
43     }
44
45     public void setMethodKey(List<String> methodKey) {
46         this.methodKey = methodKey;
47     }
48
49     public boolean isShowLog() {
50         return showLog;
51     }
52
53     public void setShowLog(boolean showLog) {
54         this.showLog = showLog;
55     }
56 }

切换主从库的持有类

 1 public class DbContextHolder {
 2
 3     /**
 4      * 线程threadLocal
 5      */
 6     private static ThreadLocal<String> contextHolder = new ThreadLocal<String>();
 7     /**
 8      * 主库:执行读写操作
 9      */
10     public static String DB_TYPE_RW = "dataSourceMaster";
11     /**
12      * 从库:执行读库操作
13      */
14     public static String DB_TYPE_R = "dataSourceSlave";
15
16     /**
17      * 默认是读写库
18      * @return
19      */
20     public static String getDbType() {
21         String db = contextHolder.get();
22         if (db == null) {
23             db = DB_TYPE_RW;
24         }
25         return db;
26     }
27
28     /**
29      * 置本线程的dbType
30      * @param str
31      */
32     public static void setDbType(String str) {
33         contextHolder.set(str);
34     }
35
36     /**
37      * @Title: clearDBType
38      * @Description: 清理连接类型
39      */
40     public static void clearDBType() {
41         contextHolder.remove();
42     }
43 }

2、使用<aop:advisor>标签织入增强处理

 1 <!-- 动态数据源 -->
 2     <bean id="dynamicDataSource" class="com.alibaba.health.dao.dynamic.DynamicDataSource">
 3         <!-- 通过key-value关联数据源 -->
 4         <property name="targetDataSources">
 5             <map>
 6                 <entry value-ref="dataSourceMaster" key="monitorDataSourceMaster"/>
 7                 <entry value-ref="dataSourceSlave" key="monitorDataSourceSlave"/>
 8             </map>
 9         </property>
10         <property name="defaultTargetDataSource" ref="dataSourceMaster"/>
11     </bean>
12
13 <!-- 通知器的具体实现:配置主从库读写分离:以select、query、find、count开头的方法走从库 -->
14     <bean id="DataBaseAdvice" class="com.jd.yao.wj.dao.dynamic.DataBaseAdvice">
15         <property name="methodKey">
16             <list>
17                 <value>select</value>
18                 <value>query</value>
19                 <value>find</value>
20                 <value>count</value>
21             </list>
22         </property>
23         <property name="showLog" value="false"/>
24     </bean>
25
26     <!-- 切面配置 -->
27     <aop:config>
28         <!-- 配置切点:第一个*表示匹配所有方法的返回值类型,.表示当前包下所有类的方法,..表示当前包下及此包下所有自爆中的所有类方法;
29              第二个*表示所有类名,第三个*表示所有方法名,(..)表示所有方法参数-->
30         <aop:pointcut expression="execution(* com.jd.yao.wj.dao..*.*(..))" id="cutPoint"/>
31         <!-- 定义通知器 -->
32         <aop:advisor advice-ref="DataBaseAdvice" pointcut-ref="cutPoint"/>
33     </aop:config>

此时就完成了主从数据库读写分离的代码和xml配置,尤其可见各种技术组件,在于是否能灵活运用。

原文地址:https://www.cnblogs.com/aoshicangqiong/p/11603470.html

时间: 2024-10-07 06:04:21

使用Adivisor配置增强处理,来实现数据库读写分离的相关文章

yii2数据库读写分离配置

原文链接:Yii中文网(yii-china.com)-yii2数据库读写分离配置 简介 数据库读写分离是在网站遇到性能瓶颈的时候最先考虑优化的步骤,那么yii2是如何做数据库读写分离的呢?本节教程来给大家普及一下yii2的数据库读写分离配置. 两个服务器的数据同步是读写分离的前提条件,但这不在yii2读写分离教程内,yii2的数据库读写分离配置,仅仅实现了在主库读写,在从库查询,那么我们首先要配置主从服务器的数据同步.详情查看linux数据库主从同步配置 配置 主从服务器数据库同步完成之后,我们

yii2的数据库读写分离配置

简介 数据库读写分离是在网站遇到性能瓶颈的时候最先考虑优化的步骤,那么yii2是如何做数据库读写分离的呢?本节教程来给大家普及一下yii2的数据库读写分离配置. 两个服务器的数据同步是读写分离的前提条件,但这不在yii2读写分离教程内,yii2的数据库读写分离配置,仅仅实现了在主库读写,在从库查询,那么我们首先要配置主从服务器的数据同步.详情查看linux数据库主从同步配置 配置 主从服务器数据库同步完成之后,我们就可以开始yii2的读写分离配置,官方也有这方面的文档,但说的并不清楚,也没有实际

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

回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是section数组,这样在修改配置时更加清晰了:而实用性上,彻底改变了读和写不能共用一个仓储对象的缺点,并且在一个事务里可以读写并存,并为了数据的一致性,使事务里的curd操作指向主库,这一点很重要! 前几篇文章的目录 EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~再续~添加对各只读服

【转】mysql数据库读写分离数据同步

转载请注明来源:mysql数据库读写分离数据同步 mysql数据库读写分离数据同步 我是用了两个xp(一个主的,一个从的)的系统测试成功的,linux系统我也做测试了,没有成功,不过我想我所遇到的问题是同一个问题,xp下的可以成功,linux下的应该也可以成功,稍候会测试,然后更新结果! PS:刚测试了下linux 可以同步成功,主服务器是xp,从服务器是centos,可以成功. 例: A机器 192.168.0.2 B机器 192.168.0.3 两个机器可以ping通,互相访问 先配置主服务

spring+mybatis利用interceptor(plugin)兑现数据库读写分离

使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是“地位相当”的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这几台数据库服务器之间进行合理分配, 这个时候,通过统一的一个DataSource来屏蔽这种请求分配的需求,从而屏蔽数据访问类与具体DataSource的耦合: 系统中存在的多台数据库服务器现在地位可能相当也可能不相当,但数据访问类在系统启动时间无法明确到底应该使用哪一个数据源进行数据访问,而必须在系统运行期间通过某种条

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

一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库的主从配置,最简单的是一台Master和一台Slave(大型网站系统的话,当然会很复杂,这里只是分析了最简单的情况).通过主从配置主从数据库保持了相同的数据,我们在进行读操作的时候访问从数据库Slave,在进行写操作的时候访问主数据库Master.这样的话就减轻了一台服务器的压力. 在进行读写分离案

asp.net实现数据库读写分离(SQLSERVER2005,ORACLE)【转】

很多时间我们肯定希望数据库的读写与程序是分离,这样可以提高业务量同时提高服务器性能,下面我来以SQL Server 2005为实例来介绍数据库读写分离方法,大家可参考. 下面我们重点介绍Sql Server 2005是如何实现负载均衡的. Sql Server 2005的新特性 SQL Server 2005对端到端(P2P)拓扑结构上事务性的复制加强了支持.P2P的拓扑结构支持无限的发布服务器,它们彼此之间可以互相交换事务. P2P拓扑是SQL Server的一个巨大进步.现在,多端点服务器可

大型网站架构演进(5)数据库读写分离

在使用缓存后,使大部分的数据读操作访问都可以不通过数据库就能完成,但是仍有一部分读操作(包括未命中缓存的,和缓存过期的)和全部的写操作需要访问数据库,当网站的访问量继续增加后,数据库会因为负载压力过高导致成为网站的性能瓶颈. 目前大部分的主流数据库都提供了主从热血功能,通过配置两台数据库的主从关系,可以将一台数据库服务器的数据同步到另一台服务器上,网站利用数据库的这一功能,可以实现数据库的读写分离,从而改善数据库的负载压力. 应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据

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

一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库的主从配置,最简单的是一台Master和一台Slave(大型网站系统的话,当然会很复杂,这里只是分析了最简单的情况).通过主从配置主从数据库保持了相同的数据,我们在进行读操作的时候访问从数据库Slave,在进行写操作的时候访问主数据库Master.这样的话就减轻了一台服务器的压力. 在进行读写分离案