SPEL(Spring Expression Language)是Spring框架中的一种表达式语言,用于在运行时对对象图进行查询和操作。SPEL提供了一种简洁而强大的语法,允许开发人员在Spring应用程序中使用表达式来访问对象的属性、调用对象的方法、进行算术运算、逻辑运算等。
代码实现
直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| public class SpringExpressionVariableExtractor {
private static final ExpressionParser PARSER = new SpelExpressionParser(); private static final TemplateParserContext PARSER_CONTEXT = new TemplateParserContext("${", "}");
private SpringExpressionVariableExtractor() { }
public static Set<String> findVars(String templateStr) { Expression expression = PARSER.parseExpression(templateStr, PARSER_CONTEXT); List<VarDef> varSet = new ArrayList<>(); findOutVarByExpression(expression, varSet); return mergeVars(varSet); }
private static void findOutVarByExpression(Expression rootExpression, List<VarDef> varSet) { if (rootExpression instanceof SpelExpression) { SpelExpression spelExpression = (SpelExpression) rootExpression; SpelNode spelNode = spelExpression.getAST(); findOutVar(spelNode, varSet); } else if (rootExpression instanceof CompositeStringExpression) { CompositeStringExpression compositeStringExpression = (CompositeStringExpression) rootExpression; Expression[] expressions = compositeStringExpression.getExpressions(); for (Expression expression : expressions) { findOutVarByExpression(expression, varSet); } } }
private static void findOutVar(SpelNode node, List<VarDef> varSet) { if (node instanceof PropertyOrFieldReference) { varSet.add(new VarDef((PropertyOrFieldReference) node)); } if (node.getChildCount() > 0) { for (int i = 0; i < node.getChildCount(); i++) { findOutVar(node.getChild(i), varSet); } } }
private static Set<String> mergeVars(List<VarDef> varDefList) { Deque<VarDef> stack = new ArrayDeque<>(); for (VarDef varDef : varDefList) { if (stack.isEmpty()) { stack.push(varDef); } else { VarDef top = stack.peek(); if (top.end + 1 == varDef.start) { top.merge(varDef); } else { stack.push(varDef); } } } return stack.stream().map(VarDef::getName).collect(Collectors.toSet()); }
@Data private static class VarDef {
private String name;
private int start;
private int end;
public VarDef(String name, int start, int end) { this.name = name; this.start = start; this.end = end; }
public VarDef(PropertyOrFieldReference reference) { this.name = reference.getName(); this.start = reference.getStartPosition(); this.end = reference.getEndPosition(); }
public void merge(VarDef def) { this.name = this.name + "." + def.name; this.end = def.end; } }
}
|
使用
1 2 3 4 5 6 7
| public class Main2 {
public static void main(String[] args) { Set<String> vars = SpringExpressionVariableExtractor.findVars("${type == 1 && serviceData.isComplete}"); System.out.println(vars); } }
|
运行结果
1
| [serviceData.isComplete, type]
|