潘志宝
2024-12-25 874dd8d939b4ae61efbb799855c9ddf328722972
提交 | 用户 | 时间
e7c126 1 package com.iailab.framework.ratelimiter.core.keyresolver.impl;
H 2
3 import cn.hutool.core.util.ArrayUtil;
4 import com.iailab.framework.ratelimiter.core.annotation.RateLimiter;
5 import com.iailab.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
6 import org.aspectj.lang.JoinPoint;
7 import org.aspectj.lang.reflect.MethodSignature;
8 import org.springframework.core.DefaultParameterNameDiscoverer;
9 import org.springframework.core.ParameterNameDiscoverer;
10 import org.springframework.expression.Expression;
11 import org.springframework.expression.ExpressionParser;
12 import org.springframework.expression.spel.standard.SpelExpressionParser;
13 import org.springframework.expression.spel.support.StandardEvaluationContext;
14
15 import java.lang.reflect.Method;
16
17 /**
18  * 基于 Spring EL 表达式的 {@link RateLimiterKeyResolver} 实现类
19  *
20  * @author iailab
21  */
22 public class ExpressionRateLimiterKeyResolver implements RateLimiterKeyResolver {
23
24     private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
25
26     private final ExpressionParser expressionParser = new SpelExpressionParser();
27
28     @Override
29     public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
30         // 获得被拦截方法参数名列表
31         Method method = getMethod(joinPoint);
32         Object[] args = joinPoint.getArgs();
33         String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method);
34         // 准备 Spring EL 表达式解析的上下文
35         StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
36         if (ArrayUtil.isNotEmpty(parameterNames)) {
37             for (int i = 0; i < parameterNames.length; i++) {
38                 evaluationContext.setVariable(parameterNames[i], args[i]);
39             }
40         }
41
42         // 解析参数
43         Expression expression = expressionParser.parseExpression(rateLimiter.keyArg());
44         return expression.getValue(evaluationContext, String.class);
45     }
46
47     private static Method getMethod(JoinPoint point) {
48         // 处理,声明在类上的情况
49         MethodSignature signature = (MethodSignature) point.getSignature();
50         Method method = signature.getMethod();
51         if (!method.getDeclaringClass().isInterface()) {
52             return method;
53         }
54
55         // 处理,声明在接口上的情况
56         try {
57             return point.getTarget().getClass().getDeclaredMethod(
58                     point.getSignature().getName(), method.getParameterTypes());
59         } catch (NoSuchMethodException e) {
60             throw new RuntimeException(e);
61         }
62     }
63
64 }