001package cn.sticki.validator.spel.parse; 002 003import cn.sticki.validator.spel.exception.SpelParserException; 004import lombok.extern.slf4j.Slf4j; 005import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 006import org.springframework.context.ApplicationContext; 007import org.springframework.context.expression.BeanFactoryResolver; 008import org.springframework.expression.spel.standard.SpelExpressionParser; 009import org.springframework.expression.spel.support.StandardEvaluationContext; 010 011/** 012 * Spel表达式解析工具 013 * 014 * @author 阿杆 015 * @version 1.0 016 * @since 2024/4/29 017 */ 018@SuppressWarnings("AlibabaConstantFieldShouldBeUpperCase") 019@Slf4j 020public class SpelParser { 021 022 private static final SpelExpressionParser parser = new SpelExpressionParser(); 023 024 private static final StandardEvaluationContext context = new StandardEvaluationContext(); 025 026 static { 027 ApplicationContext applicationContext = SpelValidatorBeanRegistrar.getApplicationContext(); 028 if (applicationContext != null) { 029 AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); 030 context.setBeanResolver(new BeanFactoryResolver(beanFactory)); 031 } else { 032 log.warn("ApplicationContext is null, SpelParser will not support spring bean reference"); 033 log.warn("If you want to use spring bean reference in SpelParser, please use @EnableSpelValidatorBeanRegistrar to enable ApplicationContext support"); 034 } 035 } 036 037 /** 038 * 解析表达式 039 * 040 * @param expression 表达式 041 * @param rootObject 用于计算表达式的根对象 042 * @return 表达式计算结果 043 */ 044 public static Object parse(String expression, Object rootObject) { 045 try { 046 Object value = parser.parseExpression(expression).getValue(context, rootObject, Object.class); 047 log.debug("======> Parse expression: [{}], result: [{}]", expression, value); 048 return value; 049 } catch (Exception e) { 050 log.error("Parse expression error, expression: [{}], message: [{}]", expression, e.getMessage()); 051 throw new SpelParserException(e); 052 } 053 } 054 055 /** 056 * 解析表达式 057 * 058 * @param expression 表达式 059 * @param rootObject 用于计算表达式的根对象 060 * @param desiredResultType 指定返回值的类型 061 * @return 表达式计算结果 062 * @throws SpelParserException 当表达式计算结果为null或者不是指定类型时抛出 063 */ 064 public static <T> T parse(String expression, Object rootObject, Class<T> desiredResultType) { 065 Object any = parse(expression, rootObject); 066 if (any == null) { 067 throw new SpelParserException("Expression [" + expression + "] calculate result can not be null"); 068 } 069 if (!desiredResultType.isInstance(any)) { 070 throw new SpelParserException("Expression [" + expression + "] calculate result must be [" + desiredResultType.getName() + "]"); 071 } 072 return desiredResultType.cast(any); 073 } 074 075}