spring读写分离
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class ChooseDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return HandleDataSource.getDataSource();
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
*
* @author yangGuang
*
*/ @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSource {
String value();
}
import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature; public class DataSourceAspect { /**
* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
} /**
* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
HandleDataSource.putDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
HandleDataSource.putDataSource(source.value());
}
} catch (Exception e) {
// System.out.println(clazz + ":" + e.getMessage());
}
} }
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();
}
public static void clearDataSource() {
holder.remove();
}
}
spring配置文件
<bean id="dataSource" class="hometree.ecs.business.db.dao.util.ChooseDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- write -->
<entry key="write" value-ref="writeDataSource"/>
<!-- read -->
<entry key="read" value-ref="readDataSource"/>
<!-- 读写 -->
<entry key="wr" value-ref="dataSourceAdmin"/>
</map> </property>
<!-- 默认 -->
<property name="defaultTargetDataSource" ref="dataSourceAdmin"/>
</bean> <!-- 激活自动代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 配置数据库注解aop -->
<bean id="dataSourceAspect" class="aa.dd.cc.DataSourceAspect" />
<aop:config>
<aop:aspect id="c" ref="dataSourceAspect">
<!--扫描下边的所有方法都要过before -->
<aop:pointcut id="tx" expression="execution(* aa.dd.cc.*.*(..))"/>
<aop:before pointcut-ref="tx" method="intercept"/> <!-- intercept是执行的方法 -->
</aop:aspect>
</aop:config>
<!-- 配置数据库注解aop -->
在方法调用上:
@DataSource("read")//read与
<entry key="read" value-ref="readDataSource"/> 对应
public void add(){
}
spring读写分离的更多相关文章
- [Spring] - 读写分离
使用Spring可以做到在应用层中实现数据库的读写分离. 参考文档: http://blog.csdn.net/lifuxiangcaohui/article/details/7280202 思路是使 ...
- spring读写分离(配置多数据源)[marked]
我们今天的主角是AbstractRoutingDataSource,在Spring2.0.1发布之后,引入了AbstractRoutingDataSource,使用该类可以实现普遍意义上的多数据源管理 ...
- 基于Spring读写分离
为什么是基于Spring的呢,因为实现方案基于Spring的事务以及AbstractRoutingDataSource(spring中的一个基础类,可以在其中放多个数据源,然后根据一些规则来确定当前需 ...
- springboot读写分离--temp
我最初的想法是: 读方法走读库,写方法走写库(一般是主库),保证在Spring提交事务之前确定数据源. 保证在Spring提交事务之前确定数据源,这个简单,利用AOP写个切换数据源的切面,让他的优先级 ...
- Spring aop应用之实现数据库读写分离
Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果 ...
- Spring 实现数据库读写分离
随着互联网的大型网站系统访问量的增高,数据库访问压力方面不断的显现而出,所以许多公司在数据库层面采用读写分离技术,也就是一个master,多个slave.master负责数据的实时更新或实时查询,而s ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 基于spring的aop实现读写分离与事务配置
项目开发中经常会遇到读写分离等多数据源配置的需求,在Java项目中可以通过Spring AOP来实现多数据源的切换. 一.Spring事务开启流程 Spring中通常通过@Transactional来 ...
- spring MVC、mybatis配置读写分离
spring MVC.mybatis配置读写分离 1.环境: 3台数据库机器,一个master,二台slave,分别为slave1,slave2 2.要实现的目标: ①使数据写入到master ②读数 ...
随机推荐
- iOS系统消息
一.键盘1.UIKeyboardWillShowNotification-将要弹出键盘2.UIKeyboardDidShowNotification-显示键盘3.UIKeyboardWillHideN ...
- css3 弹框提示样式
.common-dialog-box{ opacity: 0; filter: alpha(opacity=0); position: fixed; top: 0%; left: 50%; z-ind ...
- JavaScript闭包学习笔记
此文都是大牛们关于闭包的观点,在此只是总结. 闭包应用的两种情况即可——函数作为返回值,函数作为参数传递. 1 深入理解javascript原型和闭包 判断一个变量是不是对象非常简单.值类型的类型判断 ...
- 华为HG255D路由器使用OH3C进行中大校园网认证
之前用的上海贝尔RG100A-AA路由器,被我无情地摧残了,电源按钮挂了,只能换个路由器.由于在校内,使用OP还是比较方便的,网上淘了这款华为HG255D,店主已刷好OP,无线速率300M,想想也是值 ...
- LintCode Validate Binary Search Tree
Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...
- LintCode Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values. Given: 1 / \ 2 3 / \ 4 5 re ...
- Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting
最近每天半夜,服务器都会出现崩掉的现象,pc app 都不能正常使用 查看错误日志发现问题所在: [Wed Nov 09 08:07:28.651642 2016] [mpm_winnt:error ...
- hdu4691 Front compression ——暴力 || 后缀数组
link:http://acm.hdu.edu.cn/showproblem.php?pid=4691 暴力,数据明显太水了吧,n=10^5, O(n^2)的复杂度哎喂.想让大家暴力写直接让n=100 ...
- Safari 前端开发调试 iOS 完美解决方案
转http://www.2cto.com/kf/201403/283404.html afari 前端开发调试 iOS 完美解决方案 2014-03-05 0个评论 来源:Safari ...
- JdbcUtils 系列1
1.开发前准备 创建java pro为dbutils_1,没有lib目录,建一个即可 /dbutils_1/lib/mysql-connector-java-5.0.8-bin.jar 数据库搭建c3 ...