使用不同的根对象类型调用相同的Spring EL表达式失败

时间:2018-05-28 14:46:54

标签: java spring spring-el

让我们考虑以下测试:

@Test
public void testSameExpressionDifferentRootObjectClass() {
    SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, Thread.currentThread().getContextClassLoader());
    SpelExpressionParser parser = new SpelExpressionParser(config);
    StandardEvaluationContext context = new StandardEvaluationContext();
    Expression expr = parser.parseExpression("'Test: ' + #root");

    assertThat(expr.getValue(context, 42L)).isEqualTo("Test: 42");
    assertThat(expr.getValue(context, "string")).isEqualTo("Test: string");
    assertThat(expr.getValue(context, 42L)).isEqualTo("Test: 42");
    assertThat(expr.getValue(context, "string")).isEqualTo("Test: string");
}

第3个断言失败,但有以下异常:

  

org.springframework.expression.spel.SpelEvaluationException:EL1072E:   评估编译表达式时出现异常

     

在   org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:328)     在   org.example.ExpressionTest.testSameExpressionDifferentRootObjectClass(ExpressionProvidersTest.java:36)

     

引起:java.lang.ClassCastException:java.lang.Long无法强制转换   到spel.Ex2.getValue(未知来源)at的java.lang.String   org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:318)     ......还有31个

这对我来说是意外的,并且在关于此约束的文档中没有找到任何内容。我在这里做错了吗?

1 个答案:

答案 0 :(得分:1)

对于这种情况,您应该使用MIXED模式;看到j​​avadocs ......

public enum SpelCompilerMode {

    /**
     * The compiler is switched off; this is the default.
     */
    OFF,

    /**
     * In immediate mode, expressions are compiled as soon as possible (usually after 1 interpreted run).
     * If a compiled expression fails it will throw an exception to the caller.
     */
    IMMEDIATE,

    /**
     * In mixed mode, expression evaluation silently switches between interpreted and compiled over time.
     * After a number of runs the expression gets compiled. If it later fails (possibly due to inferred
     * type information changing) then that will be caught internally and the system switches back to
     * interpreted mode. It may subsequently compile it again later.
     */
    MIXED

}