Skip to content

Commit 519799e

Browse files
committed
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
1 parent c8f2e07 commit 519799e

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException
6868
throwIfNotNullSafe(getArgumentTypes(arguments));
6969
return ValueRef.NullValueRef.instance;
7070
}
71-
return new MethodValueRef(state);
71+
return new MethodValueRef(state, arguments);
7272
}
7373

7474
@Override
@@ -246,11 +246,11 @@ private class MethodValueRef implements ValueRef {
246246

247247
private final Object[] arguments;
248248

249-
public MethodValueRef(ExpressionState state) {
249+
public MethodValueRef(ExpressionState state, Object[] arguments) {
250250
this.evaluationContext = state.getEvaluationContext();
251251
this.value = state.getActiveContextObject().getValue();
252252
this.targetType = state.getActiveContextObject().getTypeDescriptor();
253-
this.arguments = getArguments(state);
253+
this.arguments = arguments;
254254
}
255255

256256
@Override

spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.List;
3030
import java.util.Map;
3131
import java.util.Properties;
32+
import java.util.concurrent.atomic.AtomicInteger;
3233

3334
import org.junit.Rule;
3435
import org.junit.Test;
@@ -1825,6 +1826,39 @@ public void SPR11348() {
18251826
assertEquals("two", list.get(1));
18261827
}
18271828

1829+
@Test
1830+
public void SPR11445_simple() {
1831+
StandardEvaluationContext context = new StandardEvaluationContext(new Spr11445Class());
1832+
Expression expr = new SpelExpressionParser().parseRaw("echo(parameter())");
1833+
assertEquals(1, expr.getValue(context));
1834+
}
1835+
1836+
@Test
1837+
public void SPR11445_beanReference() {
1838+
StandardEvaluationContext context = new StandardEvaluationContext();
1839+
context.setBeanResolver(new Spr11445Class());
1840+
Expression expr = new SpelExpressionParser().parseRaw("@bean.echo(@bean.parameter())");
1841+
assertEquals(1, expr.getValue(context));
1842+
}
1843+
1844+
static class Spr11445Class implements BeanResolver {
1845+
1846+
private final AtomicInteger counter = new AtomicInteger();
1847+
1848+
public int echo(int invocation) {
1849+
return invocation;
1850+
}
1851+
1852+
public int parameter() {
1853+
return counter.incrementAndGet();
1854+
}
1855+
1856+
@Override
1857+
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
1858+
return beanName.equals("bean") ? this : null;
1859+
}
1860+
}
1861+
18281862
@Test
18291863
public void SPR11494() {
18301864
Expression exp = new SpelExpressionParser().parseExpression("T(java.util.Arrays).asList('a','b')");

0 commit comments

Comments
 (0)