6 changed files with 933 additions and 88 deletions
@ -0,0 +1,66 @@ |
|||||
|
package com.example.web.aspect; |
||||
|
|
||||
|
import com.example.web.config.DataSourceContextHolder; |
||||
|
import org.aspectj.lang.JoinPoint; |
||||
|
import org.aspectj.lang.annotation.After; |
||||
|
import org.aspectj.lang.annotation.Aspect; |
||||
|
import org.aspectj.lang.annotation.Before; |
||||
|
import org.aspectj.lang.annotation.Pointcut; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Aspect |
||||
|
@Component |
||||
|
public class ReadWriteSeparationAspect { |
||||
|
|
||||
|
private static final Logger logger = LoggerFactory.getLogger(ReadWriteSeparationAspect.class); |
||||
|
|
||||
|
// 定义切入点,拦截所有Mapper方法
|
||||
|
@Pointcut("execution(* com.example.web.mapper.*Mapper.*(..))") |
||||
|
public void mapperPointcut() { |
||||
|
} |
||||
|
|
||||
|
@Before("mapperPointcut()") |
||||
|
public void beforeMapperMethod(JoinPoint joinPoint) { |
||||
|
String methodName = joinPoint.getSignature().getName(); |
||||
|
String className = joinPoint.getTarget().getClass().getSimpleName(); |
||||
|
|
||||
|
// 获取当前使用的数据源
|
||||
|
String currentDataSource = DataSourceContextHolder.getDataSource(); |
||||
|
|
||||
|
// 根据方法名判断是读操作还是写操作
|
||||
|
if (isReadOperation(methodName)) { |
||||
|
// 读操作使用从库
|
||||
|
String slaveDataSource = currentDataSource.contains("wechat") ? "wechat-slave" : "primary-slave"; |
||||
|
DataSourceContextHolder.setDataSource(slaveDataSource); |
||||
|
logger.debug("切换到从库数据源: {},执行方法: {}.{}", slaveDataSource, className, methodName); |
||||
|
} else { |
||||
|
// 写操作使用主库
|
||||
|
String masterDataSource = currentDataSource.contains("wechat") ? "wechat" : "primary"; |
||||
|
DataSourceContextHolder.setDataSource(masterDataSource); |
||||
|
logger.debug("切换到主库数据源: {},执行方法: {}.{}", masterDataSource, className, methodName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@After("mapperPointcut()") |
||||
|
public void afterMapperMethod() { |
||||
|
// 方法执行完成后清除数据源上下文
|
||||
|
DataSourceContextHolder.clearDataSource(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断是否为读操作 |
||||
|
* @param methodName 方法名 |
||||
|
* @return 是否为读操作 |
||||
|
*/ |
||||
|
private boolean isReadOperation(String methodName) { |
||||
|
// 通常查询方法以find、get、select、query、list、count等开头的方法为读操作
|
||||
|
return methodName.startsWith("find") || |
||||
|
methodName.startsWith("get") || |
||||
|
methodName.startsWith("select") || |
||||
|
methodName.startsWith("query") || |
||||
|
methodName.startsWith("list") || |
||||
|
methodName.startsWith("count"); |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
Loading…
Reference in new issue