spring aop , mysql 主从配置 实现读写分离,接下来把自己的配置过程,以及遇到的问题记录下来,方便下次操作,也希望给一些朋友带来帮助。

1.使用spring aop 拦截机制现数据源的动态选取。
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* RUNTIME
* 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
* @author yangGuang
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSource {
String value();
}
3.利用Spring的AbstractRoutingDataSource解决多数据源的问题
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class ChooseDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return HandleDataSource.getDataSource();
}
}
4.利用ThreadLocal解决线程安全问题
public class HandleDataSource {
public static final ThreadLocal<String> holder = new ThreadLocal<String>();
public static void putDataSource(String datasource) {
holder.set(datasource);
}
public static String getDataSource() {
return holder.get();
}
}
5.定义一个数据源切面类,通过aop访问,在spring配置文件中配置了,所以没有使用aop注解。
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
//@Aspect
//@Component
public class DataSourceAspect {
//@Pointcut("execution(* com.apc.cms.service.*.*(..))")
public void pointCut(){};
// @Before(value = "pointCut()")
public void before(JoinPoint point)
{
Object target = point.getTarget();
System.out.println(target.toString());
String method = point.getSignature().getName();
System.out.println(method);
Class<?>[] classz = target.getClass().getInterfaces();
Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())
.getMethod().getParameterTypes();
try {
Method m = classz[0].getMethod(method, parameterTypes);
System.out.println(m.getName());
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource data = m.getAnnotation(DataSource.class);
HandleDataSource.putDataSource(data.value());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.配置applicationContext.xml
<!-- 主库数据源 -->
<bean id="writeDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://172.22.14.6:3306/cpp?autoReconnect=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="partitionCount" value="4"/>
<property name="releaseHelperThreads" value="3"/>
<property name="acquireIncrement" value="2"/>
<property name="maxConnectionsPerPartition" value="40"/>
<property name="minConnectionsPerPartition" value="20"/>
<property name="idleMaxAgeInSeconds" value="60"/>
<property name="idleConnectionTestPeriodInSeconds" value="60"/>
<property name="poolAvailabilityThreshold" value="5"/>
</bean>
<!-- 从库数据源 -->
<bean id="readDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://172.22.14.7:3306/cpp?autoReconnect=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="partitionCount" value="4"/>
<property name="releaseHelperThreads" value="3"/>
<property name="acquireIncrement" value="2"/>
<property name="maxConnectionsPerPartition" value="40"/>
<property name="minConnectionsPerPartition" value="20"/>
<property name="idleMaxAgeInSeconds" value="60"/>
<property name="idleConnectionTestPeriodInSeconds" value="60"/>
<property name="poolAvailabilityThreshold" value="5"/>
</bean>
<!-- transaction manager, 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 注解自动载入 -->
<context:annotation-config />
<!--enale component scanning (beware that this does not enable mapper scanning!)-->
<context:component-scan base-package="com.apc.cms.persistence.rdbms" />
<context:component-scan base-package="com.apc.cms.service">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Component" />
</context:component-scan>
<context:component-scan base-package="com.apc.cms.auth" />
<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven />
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.apc.cms.model.domain" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.apc.cms.persistence" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="dataSource" class="com.apc.cms.utils.ChooseDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- write -->
<entry key="write" value-ref="writeDataSource"/>
<!-- read -->
<entry key="read" value-ref="readDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="writeDataSource"/>
</bean>
<!-- 激活自动代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 配置数据库注解aop -->
<bean id="dataSourceAspect" class="com.apc.cms.utils.DataSourceAspect" />
<aop:config>
<aop:aspect id="c" ref="dataSourceAspect">
<aop:pointcut id="tx" expression="execution(* com.apc.cms.service..*.*(..))"/>
<aop:before pointcut-ref="tx" method="before"/>
</aop:aspect>
</aop:config>
<!-- 配置数据库注解aop -->
7.使用注解,动态选择数据源,分别走读库和写库。
@DataSource("write")
public void update(User user) {
userMapper.update(user);
}
@DataSource("read")
public Document getDocById(long id) {
return documentMapper.getById(id);
}
测试写操作:可以通过应用修改数据,修改主库数据,发现从库的数据被同步更新了,所以定义的write操作都是走的写库
测试读操作: 后台修改从库数据,查看主库的数据没有被修改,在应用页面中刷新,发现读的是从库的数据,说明读写分离ok。
遇到的问题总结:
问题1:项目是maven工程,用到了Spring aop机制,除了spring的核心jar包以为,还需要用到的jar包有aspectj.jar,aspectjweaver.jar,aopalliance.jar查看项目中的pom,发现缺少依赖包,由于本地仓库没有这些jar,查找可以提供下载jar包的maven中央库库,配置到maven中,自动更新:
<repository> <id>nexus</id> <name>nexus</name> <url>http://repository.sonatype.org/content/groups/public/</url> <layout>default</layout> </repository>
配置项目依赖的jar,主要是缺少这两个。
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
lt;/dependency>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# spring
# mysql读写分离
# aop
# 读写分离
# Spring AOP切面解决数据库读写分离实例详解
# SpringMVC4+MyBatis+SQL Server2014实现数据库读写分离
# SpringBoot集成Spring Data JPA及读写分离
# 详解Spring AOP 实现主从读写分离
# Spring+MyBatis实现数据库读写分离方案
# Spring配置动态数据源实现读写分离的方法
# Spring boot实现数据库读写分离的方法
# Spring 实现数据库读写分离的示例
# 使用Spring AOP实现MySQL数据库读写分离案例分析(附demo)
# Spring动态数据源实现读写分离详解
# 自己的
# 都是
# 是从
# 这两个
# 可以通过
# 还需要
# 配置文件
# 将把
# 大家多多
# 自动更新
# 主要是
# 同步更新
# 下次
# target
# service
# pointCut
# point
# getSignature
# method
# Class
相关文章:
大型企业网站制作流程,做网站需要注册公司吗?
建站主机默认首页配置指南:核心功能与访问路径优化
如何选择香港主机高效搭建外贸独立站?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
如何快速搭建支持数据库操作的智能建站平台?
定制建站哪家更专业可靠?推荐榜单揭晓
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
,网站推广常用方法?
如何用PHP快速搭建CMS系统?
建站主机选虚拟主机还是云服务器更好?
长沙企业网站制作哪家好,长沙水业集团官方网站?
深圳网站制作平台,深圳市做网站好的公司有哪些?
公司网站制作需要多少钱,找人做公司网站需要多少钱?
郑州企业网站制作公司,郑州招聘网站有哪些?
网站制作报价单模板图片,小松挖机官方网站报价?
营销式网站制作方案,销售哪个网站招聘效果最好?
淘宝制作网站有哪些,淘宝网官网主页?
已有域名建站全流程解析:网站搭建步骤与建站工具选择
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
如何快速查询域名建站关键信息?
大同网页,大同瑞慈医院官网?
怎么将XML数据可视化 D3.js加载XML
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
如何在橙子建站上传落地页?操作指南详解
公众号网站制作网页,微信公众号怎么制作?
简单实现Android文件上传
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
建站org新手必看:2024最新搭建流程与模板选择技巧
大连 网站制作,大连天途有线官网?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
如何基于云服务器快速搭建网站及云盘系统?
昆明网站制作哪家好,昆明公租房申请网上登录入口?
如何用AWS免费套餐快速搭建高效网站?
如何在万网自助建站平台快速创建网站?
css网站制作参考文献有哪些,易聊怎么注册?
建站主机选购指南:核心配置与性价比推荐解析
如何批量查询域名的建站时间记录?
代购小票制作网站有哪些,购物小票的简要说明?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
深入理解Android中的xmlns:tools属性
建站中国官网:模板定制+SEO优化+建站流程一站式指南
如何正确选择百度移动适配建站域名?
天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?
如何在VPS电脑上快速搭建网站?
沈阳制作网站公司排名,沈阳装饰协会官方网站?
实例解析Array和String方法
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
免费视频制作网站,更新又快又好的免费电影网站?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
详解jQuery停止动画——stop()方法的使用
*请认真填写需求信息,我们会在24小时内与您取得联系。