Regex SpEL表达式-标识表达式中声明的字段?

Regex SpEL表达式-标识表达式中声明的字段?,regex,spring,spring-el,Regex,Spring,Spring El,下面的代码使用Map对象中定义的数据值计算SpEL表达式 // data map Map dataMap = new HashMap(); dataMap.put("abc",1); dataMap.put("def",2); dataMap.put("xyz",1); dataMap.put("qwerty",2); // spel rule expression String ruleExpression = "#abc+#def"; // Set evaluation context

下面的代码使用Map对象中定义的数据值计算SpEL表达式

// data map
Map dataMap = new HashMap();
dataMap.put("abc",1);
dataMap.put("def",2);
dataMap.put("xyz",1);
dataMap.put("qwerty",2);

// spel rule expression
String ruleExpression = "#abc+#def";

// Set evaluation context
StandardEvaluationContext stdContext = new StandardEvaluationContext();
stdContext.setVariables(map);

// Evaluate the SpEL expression
ExpressionParser parser = new SpelExpressionParser();
Object returnValue = parser.parseExpression(ruleExpression).getValue(stdContext);

// returnValue = 3 :-)
在现实世界中,我们的映射是基于DB查询结果集填充的,“ruleExpression”仅在运行时已知。我有一个新的需求,需要记录“ruleExpression”中定义的值,以便生成这样的字符串

abc=1,def=2
使用蛮力方法可能会看到我们使用正则表达式解析“ruleExpression”字符串以识别以“#”开头的字段名,但我可以看到,随着ruleExpression复杂性的增加,这可能会变得混乱

我想知道,既然SpEl引擎必须在parseExpress()阶段识别“ruleExpression”中声明的字段,那么我们有没有办法重用这个逻辑


编辑-我确实在类上遇到了VariableScope私有内部类,它似乎做了我想做的事情,但遗憾的是它不可访问。

您可以尝试覆盖
中的lookupVariable
,并在其中添加您的登录。将
stdContext
替换为以下内容将捕获每个使用的变量:

    StandardEvaluationContext stdContext = new StandardEvaluationContext() {
        @Override
        public Object lookupVariable(String name) {
            Object value = super.lookupVariable(name);
            //do logging here
            System.out.println(name + "=" + value);
            return value;
        }
    };
这将产生:

abc=1
def=2
这将只捕获从变量中使用的值。来自bean或其他对象等的任何内容都不会经过
lookupVariable
。也不会使用从未使用过的变量值(例如,由于条件限制)