mirror of https://gitee.com/y_project/RuoYi.git
Pre Merge pull request !352 from 摸摸鼻子/master
commit
201576b5a1
|
@ -25,4 +25,10 @@ public @interface DataSource
|
||||||
* 切换数据源名称
|
* 切换数据源名称
|
||||||
*/
|
*/
|
||||||
public DataSourceType value() default DataSourceType.MASTER;
|
public DataSourceType value() default DataSourceType.MASTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支持通过el表达式从参数获取切换名称
|
||||||
|
* example: elValue="#field" (从参数获取) 或 "#pojo.field" (从对象获取)
|
||||||
|
*/
|
||||||
|
String elValue() default "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package com.ruoyi.common.enums;
|
package com.ruoyi.common.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据源
|
* 数据源
|
||||||
*
|
*
|
||||||
|
@ -15,5 +19,16 @@ public enum DataSourceType
|
||||||
/**
|
/**
|
||||||
* 从库
|
* 从库
|
||||||
*/
|
*/
|
||||||
SLAVE
|
SLAVE;
|
||||||
|
|
||||||
|
private static final Set<String> DATA_SOURCE_TYPE_SET;
|
||||||
|
|
||||||
|
static {
|
||||||
|
DATA_SOURCE_TYPE_SET = Arrays.stream(DataSourceType.values())
|
||||||
|
.map(DataSourceType::name).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String sourceType){
|
||||||
|
return DATA_SOURCE_TYPE_SET.contains(sourceType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.ruoyi.common.utils.el;
|
||||||
|
|
||||||
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.context.expression.AnnotatedElementKey;
|
||||||
|
import org.springframework.context.expression.CachedExpressionEvaluator;
|
||||||
|
import org.springframework.context.expression.MethodBasedEvaluationContext;
|
||||||
|
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||||
|
import org.springframework.core.ParameterNameDiscoverer;
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
import org.springframework.expression.Expression;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : mudi
|
||||||
|
* @date : Created in 2021/12/3 21:02
|
||||||
|
* @description :
|
||||||
|
* @modified By :
|
||||||
|
*/
|
||||||
|
public class ExpressionEvaluator<T> extends CachedExpressionEvaluator {
|
||||||
|
private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||||
|
private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<>(64);
|
||||||
|
private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64);
|
||||||
|
|
||||||
|
|
||||||
|
public EvaluationContext createEvaluationContext(Object object, Class<?> targetClass, Method method, Object[] args) {
|
||||||
|
Method targetMethod = getTargetMethod(targetClass, method);
|
||||||
|
ExpressionRootObject root = new ExpressionRootObject(object, args);
|
||||||
|
return new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public T condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) {
|
||||||
|
return getExpression(this.conditionCache, elementKey, conditionExpression).getValue(evalContext, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Method getTargetMethod(Class<?> targetClass, Method method) {
|
||||||
|
AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass);
|
||||||
|
Method targetMethod = this.targetMethodCache.get(methodKey);
|
||||||
|
if (targetMethod == null) {
|
||||||
|
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
|
||||||
|
if (targetMethod == null) {
|
||||||
|
targetMethod = method;
|
||||||
|
}
|
||||||
|
this.targetMethodCache.put(methodKey, targetMethod);
|
||||||
|
}
|
||||||
|
return targetMethod;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.ruoyi.common.utils.el;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : mudi
|
||||||
|
* @date : Created in 2021/12/3 21:03
|
||||||
|
* @description :
|
||||||
|
* @modified By :
|
||||||
|
*/
|
||||||
|
public class ExpressionRootObject {
|
||||||
|
private final Object object;
|
||||||
|
private final Object[] args;
|
||||||
|
|
||||||
|
public ExpressionRootObject(Object object, Object[] args) {
|
||||||
|
this.object = object;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
package com.ruoyi.framework.aspectj;
|
package com.ruoyi.framework.aspectj;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.ruoyi.common.enums.DataSourceType;
|
||||||
|
import com.ruoyi.common.utils.el.ExpressionEvaluator;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
@ -8,8 +12,10 @@ import org.aspectj.lang.annotation.Pointcut;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.expression.AnnotatedElementKey;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.ruoyi.common.annotation.DataSource;
|
import com.ruoyi.common.annotation.DataSource;
|
||||||
import com.ruoyi.common.config.datasource.DynamicDataSourceContextHolder;
|
import com.ruoyi.common.config.datasource.DynamicDataSourceContextHolder;
|
||||||
|
@ -27,6 +33,8 @@ public class DataSourceAspect
|
||||||
{
|
{
|
||||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private ExpressionEvaluator<String> evaluator = new ExpressionEvaluator<>();
|
||||||
|
|
||||||
@Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
|
@Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
|
||||||
+ "|| @within(com.ruoyi.common.annotation.DataSource)")
|
+ "|| @within(com.ruoyi.common.annotation.DataSource)")
|
||||||
public void dsPointCut()
|
public void dsPointCut()
|
||||||
|
@ -34,6 +42,18 @@ public class DataSourceAspect
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getValueByEl(DataSource dataSource, JoinPoint joinPoint)
|
||||||
|
{
|
||||||
|
if (Objects.equals(dataSource.elValue(), ""))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvaluationContext evaluationContext = evaluator.createEvaluationContext(joinPoint.getTarget(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs());
|
||||||
|
AnnotatedElementKey methodKey = new AnnotatedElementKey(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getTarget().getClass());
|
||||||
|
return evaluator.condition(dataSource.elValue(), methodKey, evaluationContext, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Around("dsPointCut()")
|
@Around("dsPointCut()")
|
||||||
public Object around(ProceedingJoinPoint point) throws Throwable
|
public Object around(ProceedingJoinPoint point) throws Throwable
|
||||||
{
|
{
|
||||||
|
@ -41,7 +61,9 @@ public class DataSourceAspect
|
||||||
|
|
||||||
if (StringUtils.isNotNull(dataSource))
|
if (StringUtils.isNotNull(dataSource))
|
||||||
{
|
{
|
||||||
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
|
String elValue = getValueByEl(dataSource, point);
|
||||||
|
String value = DataSourceType.contains(elValue) ? elValue : dataSource.value().name();
|
||||||
|
DynamicDataSourceContextHolder.setDataSourceType(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
Loading…
Reference in New Issue