Spel 表达式

SpelUtils工具类

import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.TypeUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.cglib.beans.BeanMap; import org.springframework.context.expression.MapAccessor; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.ClassUtils; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** * SpelUtils * * @author kancy * @date 2022/8/27 20:51 */ public class SpelUtils { /** * 用于SpEL表达式解析. */ private static final SpelExpressionParser parser = new SpelExpressionParser(); /** * 用于获取方法参数定义名字. */ private static final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer(); /** * 解析 * * @param spel spel * @param params 参数 map或者实体 * @param returnClass 返回类 * @return {@link T} */ public static <T> T parse(String spel, Object params, Class<T> returnClass){ return TypeUtils.cast(parse(spel, params), returnClass, ParserConfig.getGlobalInstance()); } /** * 解析 * * @param spel spel * @param params 参数 map或者实体 * @return {@link Object} */ public static Object parse(String spel, Object params){ // 解析过后的Spring表达式对象 Expression expression = parser.parseExpression(spel); // spring的表达式上下文对象 EvaluationContext context = new StandardEvaluationContext(params); if (ClassUtils.isPrimitiveOrWrapper(params.getClass()) || params instanceof String || params instanceof Collection){ return expression.getValue(context); } if (params instanceof Map){ // 这里很关键,如果没有配置MapAccessor,那么只能用['c']['a']这种解析方式 context.getPropertyAccessors().add(new MapAccessor()); } else { if (!params.getClass().getName().startsWith("java.")){ BeanMap beanMap = BeanMap.create(params); // 设置变量 beanMap.forEach((k,v) -> context.setVariable(String.valueOf(k), v)); } } return expression.getValue(context); } /** * 通过spel生成key * * @param spELString spel * @param method 方法 * @param args 参数 * @return {@link String} */ public static String generateKeyBySpEL(String spELString, Method method, Object[] args) { // 解析过后的Spring表达式对象 Expression expression = parser.parseExpression(spELString); // 使用spring的DefaultParameterNameDiscoverer获取方法形参名数组 String[] paramNames = nameDiscoverer.getParameterNames(method); // 初始化上下文 if (Objects.isNull(paramNames) || method.getParameterCount() <= 0 || Objects.isNull(args) || args.length <= 0){ return String.valueOf(expression.getValue()); } // spring的表达式上下文对象 EvaluationContext context; if (method.getParameterCount() == 1 && Objects.nonNull(args[0])){ // 一个EvaluationContext只能有一个RootObject,引用它的属性时,可以不加前缀 context = new StandardEvaluationContext(args[0]); if (args[0] instanceof Map){ // 这里很关键,如果没有配置MapAccessor,那么只能用['c']['a']这种解析方式 context.getPropertyAccessors().add(new MapAccessor()); } context.setVariable(paramNames[0], args[0]); } else { Map<String, Object> rootObject = new HashMap<>(); for (int i = 0; i < method.getParameterCount(); i++) { rootObject.put(paramNames[i], args[i]); } context = new StandardEvaluationContext(rootObject); // 这里很关键,如果没有配置MapAccessor,那么只能用['c']['a']这种解析方式 context.getPropertyAccessors().add(new MapAccessor()); // 设置变量 rootObject.forEach(context::setVariable); } return String.valueOf(expression.getValue(context)); } /** * 通过spel生成key * * @param spELString spel * @param joinPoint 连接点 * @return {@link String} */ public static String generateKeyBySpEL(String spELString, JoinPoint joinPoint) { Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); Object[] args = joinPoint.getArgs(); return generateKeyBySpEL(spELString, method, args); } }

参考文档


__EOF__

本文作者゛鱼记忆不止七秒つ
本文链接https://www.cnblogs.com/kancy/p/spel.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   kancy  阅读(227)  评论(0编辑  收藏  举报
相关博文:
点击右上角即可分享
微信分享提示