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