From becc926380ca6084bbcacb944aec4adbc491b562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Sun, 4 Feb 2024 16:33:09 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96RateLimiter=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aspectj/RateLimiterAspect.java | 70 +++++++------------ .../src/main/resources/spel-extension.json | 7 ++ 2 files changed, 34 insertions(+), 43 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/spel-extension.json diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java index 8f3a5caf..02735b07 100644 --- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java @@ -1,29 +1,29 @@ package org.dromara.common.ratelimiter.aspectj; -import cn.hutool.core.util.ArrayUtil; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MessageUtils; import org.dromara.common.core.utils.ServletUtils; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.ratelimiter.annotation.RateLimiter; import org.dromara.common.ratelimiter.enums.LimitType; import org.dromara.common.redis.utils.RedisUtils; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.reflect.MethodSignature; import org.redisson.api.RateType; +import org.springframework.context.expression.BeanFactoryResolver; +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 org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; import org.springframework.expression.common.TemplateParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; import java.lang.reflect.Method; @@ -44,21 +44,18 @@ public class RateLimiterAspect { * 定义spel解析模版 */ private final ParserContext parserContext = new TemplateParserContext(); - /** - * 定义spel上下文对象进行解析 - */ - private final EvaluationContext context = new StandardEvaluationContext(); /** * 方法参数解析器 */ private final ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); + @Before("@annotation(rateLimiter)") - public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable { + public void doBefore(JoinPoint point, RateLimiter rateLimiter) { int time = rateLimiter.time(); int count = rateLimiter.count(); - String combineKey = getCombineKey(rateLimiter, point); try { + String combineKey = getCombineKey(rateLimiter, point); RateType rateType = RateType.OVERALL; if (rateLimiter.limitType() == LimitType.CLUSTER) { rateType = RateType.PER_CLIENT; @@ -76,42 +73,29 @@ public class RateLimiterAspect { if (e instanceof ServiceException) { throw e; } else { - throw new RuntimeException("服务器限流异常,请稍候再试"); + throw new RuntimeException("服务器限流异常,请稍候再试", e); } } } - public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { + private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { String key = rateLimiter.key(); - // 获取方法(通过方法签名来获取) - MethodSignature signature = (MethodSignature) point.getSignature(); - Method method = signature.getMethod(); - Class targetClass = method.getDeclaringClass(); - // 判断是否是spel格式 - if (StringUtils.containsAny(key, "#")) { - // 获取参数值 + if (StringUtils.isNotBlank(key)) { + MethodSignature signature = (MethodSignature) point.getSignature(); + Method targetMethod = signature.getMethod(); Object[] args = point.getArgs(); - // 获取方法上参数的名称 - String[] parameterNames = pnd.getParameterNames(method); - if (ArrayUtil.isEmpty(parameterNames)) { - throw new ServiceException("限流key解析异常!请联系管理员!"); - } - for (int i = 0; i < parameterNames.length; i++) { - context.setVariable(parameterNames[i], args[i]); - } - // 解析返回给key - try { - Expression expression; - if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) - && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { - expression = parser.parseExpression(key, parserContext); - } else { - expression = parser.parseExpression(key); - } - key = expression.getValue(context, String.class) + ":"; - } catch (Exception e) { - throw new ServiceException("限流key解析异常!请联系管理员!"); + //noinspection DataFlowIssue + MethodBasedEvaluationContext context = + new MethodBasedEvaluationContext(null, targetMethod, args, pnd); + context.setBeanResolver(new BeanFactoryResolver(SpringUtils.getBeanFactory())); + Expression expression; + if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) + && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { + expression = parser.parseExpression(key, parserContext); + } else { + expression = parser.parseExpression(key); } + key = expression.getValue(context, String.class); } StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY); stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":"); diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/spel-extension.json b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/spel-extension.json new file mode 100644 index 00000000..64a0e1be --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/spel-extension.json @@ -0,0 +1,7 @@ +{ + "org.dromara.common.ratelimiter.annotation.RateLimiter@key": { + "method": { + "parameters": true + } + } +}