数据库读写分离(aop方式完整实现)
最近項(xiàng)目要支持讀寫分離, 網(wǎng)上找了很多,但都是不太完整,我自己整理了下供大家參考。
我的項(xiàng)目使用的框架: springMvc+spring+hibernate+springJPA+maven, 數(shù)據(jù)庫連接池用阿里的druid。
1.?新建一個DynamicDataSource類,?繼承spring的AbstractRoutingDataSource?類,
并重寫determineCurrentLookupKey()方法,如下:?
2.?新建DataSourceSwitcher類,?實(shí)現(xiàn)數(shù)據(jù)源選擇:
?
3.?新建切面類,?判斷如果調(diào)用方法以query,list,get方法開頭的,?切換為查詢庫:?
package com.dataSource;import java.lang.reflect.Method; import java.util.List;import org.apache.log4j.Logger; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.ThrowsAdvice;/*** 配置AOP切面類,動態(tài)切換讀/寫數(shù)據(jù)庫。* <p>* Copyright: Copyright (c) 2015-3-9 下午3:16:51* <p>* Company: * <p>* * @author macl@c-platform.com* @version 1.0.0*/ public class DataSourceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {private static final Logger log = Logger.getLogger(DataSourceAdvice.class);private String logInfo;// 需要切換到從庫(讀庫)的方法名前綴private List<String> slaveMethods;/*** service方法執(zhí)行之前被調(diào)用.*/@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {logInfo = String.format("before切入點(diǎn):%s-->%s(),切換到:", target.getClass().getName(), method.getName());String methodName = method.getName();boolean hasSwitchedSlave = false;for (String slaveMethod : slaveMethods) {if (methodName.startsWith(slaveMethod)) {if (log.isDebugEnabled()) {log.debug(logInfo + DataSourceSwitcher.SLAVE_DATA_SOURCE);}hasSwitchedSlave = true;DataSourceSwitcher.setSlave();break;}}if (!hasSwitchedSlave) {if (log.isDebugEnabled()) {log.debug(logInfo + "切換到:" + DataSourceSwitcher.MASTER_DATA_SOURCE);}DataSourceSwitcher.setMaster();}}/*** service方法執(zhí)行完之后被調(diào)用.*/@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {}/*** 拋出Exception之后被調(diào)用。* * @param method* @param args* @param target* @param ex* @throws Throwable*/public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {logInfo = String.format("after throwing:%s類中%s方法,", target.getClass().getName(), method.getName());log.error(logInfo + "發(fā)生異常:" + ex.getMessage() + ",切換到:" + DataSourceSwitcher.SLAVE_DATA_SOURCE);DataSourceSwitcher.setSlave();}public List<String> getSlaveMethods() {return slaveMethods;}public void setSlaveMethods(List<String> slaveMethods) {this.slaveMethods = slaveMethods;} }4.? spring配置文件中, 配置數(shù)據(jù)源:
?
?
?
5.?AOP配置(注意, 可以在service層切換(推薦), 也可以在控制器層切換):
截圖為在控制層切換配置, 附件中的context.xml中給的是在service/dao層切換的配置方式。
6.??mvc層支持aop(如果aop切換配置在控制層, 則需要配置這步):
7.?特殊類可以硬編碼:
??????切換到主庫?:?DataSourceSwitcher.setMaster();
????? 比如?,?登錄攔截器RoleGenInterceptor.java?-->?genLocalSession()
?附件下載地址
總結(jié)
以上是生活随笔為你收集整理的数据库读写分离(aop方式完整实现)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DNS服务器的默认区域文件名,DNS服务
- 下一篇: pc调试微信h5页面