Browse files

Fix double SPeL evaluation of parameter

 When a node of an SPeL expression was a call to a bean referenced
 in a method argument, the expression was resolved twice.

 The resolved arguments are now specified to MethodValueRef instead
 of resolving the arguments again in the constructor

 Issue: SPR-11445
  • Loading branch information...
1 parent c8f2e07 commit 519799e1cf414615ef0a7a26d5dde0478a47b96d @snicoll snicoll committed Mar 6, 2014
View
6 spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java
@@ -68,7 +68,7 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException
throwIfNotNullSafe(getArgumentTypes(arguments));
return ValueRef.NullValueRef.instance;
}
- return new MethodValueRef(state);
+ return new MethodValueRef(state, arguments);
}
@Override
@@ -246,11 +246,11 @@ public String toStringAST() {
private final Object[] arguments;
- public MethodValueRef(ExpressionState state) {
+ public MethodValueRef(ExpressionState state, Object[] arguments) {
this.evaluationContext = state.getEvaluationContext();
this.value = state.getActiveContextObject().getValue();
this.targetType = state.getActiveContextObject().getTypeDescriptor();
- this.arguments = getArguments(state);
+ this.arguments = arguments;
}
@Override
View
34 spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Rule;
import org.junit.Test;
@@ -1826,6 +1827,39 @@ public void SPR11348() {
}
@Test
+ public void SPR11445_simple() {
+ StandardEvaluationContext context = new StandardEvaluationContext(new Spr11445Class());
+ Expression expr = new SpelExpressionParser().parseRaw("echo(parameter())");
+ assertEquals(1, expr.getValue(context));
+ }
+
+ @Test
+ public void SPR11445_beanReference() {
+ StandardEvaluationContext context = new StandardEvaluationContext();
+ context.setBeanResolver(new Spr11445Class());
+ Expression expr = new SpelExpressionParser().parseRaw("@bean.echo(@bean.parameter())");
+ assertEquals(1, expr.getValue(context));
+ }
+
+ static class Spr11445Class implements BeanResolver {
+
+ private final AtomicInteger counter = new AtomicInteger();
+
+ public int echo(int invocation) {
+ return invocation;
+ }
+
+ public int parameter() {
+ return counter.incrementAndGet();
+ }
+
+ @Override
+ public Object resolve(EvaluationContext context, String beanName) throws AccessException {
+ return beanName.equals("bean") ? this : null;
+ }
+ }
+
+ @Test
public void SPR11494() {
Expression exp = new SpelExpressionParser().parseExpression("T(java.util.Arrays).asList('a','b')");
List<String> list = (List<String>) exp.getValue();

0 comments on commit 519799e

Please sign in to comment.