package com.iailab.framework.common.util.spring; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.expression.EvaluationContext; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.Map; /** * Spring EL 表达式的工具类 * * @author mashu */ public class SpringExpressionUtils { /** * Spring EL 表达式解析器 */ private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); /** * 参数名发现器 */ private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer(); private SpringExpressionUtils() { } /** * 从切面中,单个解析 EL 表达式的结果 * * @param joinPoint 切面点 * @param expressionString EL 表达式数组 * @return 执行界面 */ public static Object parseExpression(JoinPoint joinPoint, String expressionString) { Map result = parseExpressions(joinPoint, Collections.singletonList(expressionString)); return result.get(expressionString); } /** * 从切面中,批量解析 EL 表达式的结果 * * @param joinPoint 切面点 * @param expressionStrings EL 表达式数组 * @return 结果,key 为表达式,value 为对应值 */ public static Map parseExpressions(JoinPoint joinPoint, List expressionStrings) { // 如果为空,则不进行解析 if (CollUtil.isEmpty(expressionStrings)) { return MapUtil.newHashMap(); } // 第一步,构建解析的上下文 EvaluationContext // 通过 joinPoint 获取被注解方法 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); // 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组 String[] paramNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method); // Spring 的表达式上下文对象 EvaluationContext context = new StandardEvaluationContext(); // 给上下文赋值 if (ArrayUtil.isNotEmpty(paramNames)) { Object[] args = joinPoint.getArgs(); for (int i = 0; i < paramNames.length; i++) { context.setVariable(paramNames[i], args[i]); } } // 第二步,逐个参数解析 Map result = MapUtil.newHashMap(expressionStrings.size(), true); expressionStrings.forEach(key -> { Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context); result.put(key, value); }); return result; } }