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

时间:2014-11-14 11:49:54

标签: 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
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私有内部类,它看起来像我想要的那样但是它无法访问。

1 个答案:

答案 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。也不会使用从未使用的变量值(例如由于条件)。