我有以下代码,它使用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 :-)
在现实世界中,我们的地图是根据数据库查询结果集和“规则表达式”填充的。只在运行时才知道。我有一个新的要求,要记录" ruleExpression'中定义的值。这样生成了这样的字符串
abc=1,def=2
蛮力方法可能会让我们解析' ruleExpression'用于标识以'#'开头的字段名称的字符串使用正则表达式,但我可以看到,当ruleExpression的复杂性增加时,这可能会变得混乱。
我想知道,因为SpEl引擎必须识别“规则”中声明的字段'在parseExpress()阶段,有没有办法让我们重用这个逻辑?
编辑 - 我确实遇到了org.springframework.expression.spel.ExpressionState类的VariableScope私有内部类,它看起来像我想要的那样但是它无法访问。
答案 0 :(得分:1)
您可以尝试覆盖StandardExpressionContext中的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
。也不会使用从未使用的变量值(例如由于条件)。