Spring aop应用之实现数据库读写分离
Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果从库或数据库有多个的时候,需要配置的信息会越来越多,远远不够优雅,在我们编程界有一个规 范:约定优于配置。所以就用Sping的aop实现了一个简单的数据库分离方案,具体实现代码放在了Github上,地址如下:
https://github.com/bridgeli/practical-util/tree/master/src/main/java/cn/bridgeli
读者如果想使用再简单的方法就是把这个代码download下来,放到自己的项目里面,当然更优雅的方式是:打成jar包,放到项目里面了,具体打jar的方法,老夫就不在这里多说了,相信看这篇文章的读者肯定都会了。当然仅仅有这份代码,他们是不会自动生效的,既然是使用Spring的Aop实现数据库读写分离,
所以肯定会有牵涉到Aop的配置了,所以在spring-mybatis.xml中有如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 配置写数据源 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${bridgeli.jdbc.driver}" />
<property name="url" value="${bridgeli.jdbc.url}" />
<property name="username" value="${bridgeli.jdbc.username}" />
<property name="password" value="${bridgeli.jdbc.password}" />
<property name="validationQuery" value="${bridgeli.jdbc.validationQuery}" />
<property name="initialSize" value="1" />
<property name="maxActive" value="20" />
<property name="minIdle" value="0" />
<property name="maxWait" value="60000" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="25200000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="1800" />
<property name="logAbandoned" value="true" />
<property name="filters" value="stat" />
</bean> <!-- 配置读数据源 -->
<bean id="parentSlaveDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${bridgeli.jdbc.driver}" />
<property name="validationQuery" value="${bridgeli.jdbc.validationQuery}" />
<property name="initialSize" value="1" />
<property name="maxActive" value="20" />
<property name="minIdle" value="0" />
<property name="maxWait" value="60000" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="25200000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="1800" />
<property name="logAbandoned" value="true" />
<property name="filters" value="stat" />
</bean>
<bean id="slaveDataSource1" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" parent="parentSlaveDataSource">
<property name="url" value="${bridgeli_slave1.jdbc.url}" />
<property name="username" value="${bridgeli_slave1.jdbc.username}" />
<property name="password" value="${bridgeli_slave1.jdbc.password}" />
</bean> <bean id="dataSource" class="cn.bridgeli.datasource.MasterSlaveDataSource">
<property name="targetDataSources">
<map>
<entry key-ref="masterDataSource" value-ref="masterDataSource"/>
<entry key-ref="slaveDataSource1" value-ref="slaveDataSource1"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="masterDataSource"/>
<property name="masterSlaveSelector" ref="dataSelector"/>
</bean> <bean id="dataSelector" class="cn.bridgeli.datasource.MasterSlaveSelectorByPoll">
<property name="masters">
<list>
<ref bean="masterDataSource"/>
</list>
</property>
<property name="slaves">
<list>
<ref bean="slaveDataSource1"/>
</list>
</property>
<property name="defaultDataSource" ref="masterDataSource"/>
</bean> <aop:aspectj-autoproxy/> <!-- mybaits 数据工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 自动扫描所有注解的路径 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.bridgeli.mapper" />
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean> <!-- 数据库切面 -->
<bean id="masterSlaveAspect" class="cn.bridgeli.datasource.MasterSlaveAspect">
<property name="prefixMasters">
<list>
<value>save</value>
<value>update</value>
<value>delete</value>
</list>
</property>
</bean>
<aop:config>
<aop:aspect id="c" ref="masterSlaveAspect">
<aop:pointcut id="tx" expression="execution(* cn.bridgeli.service..*.*(..))"/>
<aop:before pointcut-ref="tx" method="before"/>
</aop:aspect>
</aop:config> <context:annotation-config />
<context:component-scan base-package="cn.bridgeli" />
</beans>
这样我们就很优雅的利用Spring的Aop实现了对数据库的读写分离,读的时候走slaveDataSource1这个数据源,写的时候走masterDataSource这个数据源。
哎,等等,这里哪里体现了约定优于配置这一规范,他们怎么知道哪些方法走读库哪些走写库?同学你别急,仔细读读这个配置文件,你就会发现在第98行,配置了一个MasterSlaveAspect,
也就是说代码里面service层(为什么是service层?)的方法以这里面配置的这些关键字打头,都将会走写库,所以当我们想让一个方法走主库的时候,必须在这个地方添加该方法的前缀或者用这里面已有的前缀,
这就要求我们必须约定好走主库的方法的打头,即约定优于配置。
Spring aop应用之实现数据库读写分离的更多相关文章
- Spring AOP /代理模式/事务管理/读写分离/多数据源管理
参考文章: http://www.cnblogs.com/MOBIN/p/5597215.html http://www.cnblogs.com/fenglie/articles/4097759.ht ...
- 原理解密 → Spring AOP 实现动态数据源(读写分离),底层原理是什么
开心一刻 女孩睡醒玩手机,收到男孩发来一条信息:我要去跟我喜欢的人表白了! 女孩的心猛的一痛,回了条信息:去吧,祝你好运! 男孩回了句:但是我没有勇气说不来,怕被打! 女孩:没事的,我相信你!此时女孩 ...
- spring AOP 实现事务和主从读写分离
1 切面 是个类 2 切入点 3 连接点 4 通知 是个方法 5 配置文件 <?xml version="1.0" encoding="UTF-8"?&g ...
- spring+mybatis利用interceptor(plugin)兑现数据库读写分离
使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是"地位相当"的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这 ...
- Spring+MyBatis实现数据库读写分离方案
推荐第四种:https://github.com/shawntime/shawn-rwdb 方案1 通过MyBatis配置文件创建读写分离两个DataSource,每个SqlSessionFactor ...
- [转]Spring数据库读写分离
数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力. 主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在 ...
- 161220、使用Spring AOP实现MySQL数据库读写分离案例分析
一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...
- 170301、使用Spring AOP实现MySQL数据库读写分离案例分析
使用Spring AOP实现MySQL数据库读写分离案例分析 原创 2016-12-29 徐刘根 Java后端技术 一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案 ...
- 使用Spring AOP实现MySQL数据库读写分离案例分析
一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...
随机推荐
- 探索ASP.NET MVC5系列之~~~1.基础篇---必须知道的小技能
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#mvc 本章D ...
- MyEclipse生成注册码
今天正在使用的MyEclipse出现了使用过期,在网上发现一个可以生成注册码的程序,现在分享给各位. /** * myEclipse生成注册码 * 点击顶部:MyEclipse --> subs ...
- 如何快速优化手游性能问题?从UGUI优化说起
WeTest 导读 本文作者从自身多年的Unity项目UI开发及优化的经验出发,从UGUI,CPU,GPU以及unity特有资源等几个维度,介绍了unity手游性能优化的一些方法. 在之前的文 ...
- 【云知道】LoadRunner 录制问题集锦
关键词:各路录制小白汇集于此 虽然知道君对录制不感冒,但总是看到扎堆的人说这些问题,忍不住要站出来了. 百度虽好,帮助了很多小白,但关键是百度并没有排除错误内容,经过历史的几年传播,错的都快变对的了, ...
- 在centos7上安装ClamAV杀毒,并杀毒(centos随机英文10字母)成功
前言 上传文件的时候发现总是失败,查看top发现有个进程一直cpu占用80%以上,而且名称还是随机数.kill之后,一会儿又重新生成了.突然发现居然没有在服务端杀毒的经历.在此处补齐. 安装clama ...
- springmvc+bootstrap+jquerymobile完整搭建案例(提供下载地址)
用一张简单的截图说明下,然后提供一个下载地址. bootstrap的大部分样式官方都是写好的,所以只需要class="官方样式即可",具体可以看官方的案例,下面来个地址 http: ...
- Android中Fragment与Activity之间的交互(两种实现方式)
(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...
- Flexbox 自由的布局
css3提出了一种新的布局方式.她并没有以摧枯拉朽之势博得我的喜爱.我和她的故事总是伴随着苦涩的味道.世道变了,总要做出些选择才能跟紧步伐.她很强大,能满足你天马行空的需求而不必抓掉一大把头发.她却很 ...
- 让Unity NavMesh为我所用
Unity里面整合了一个NavMesh功能,虽然让人又爱又恨. 但当你在其他地方需要这个NavMesh的数据时,就更让人欲罢不能了. 比如说服务器需要Unity的NavMesh数据时. 比如说你想将U ...
- MapReduce剖析笔记之五:Map与Reduce任务分配过程
在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...