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
This commit is contained in:
parent
c8f2e07182
commit
519799e1cf
|
|
@ -68,7 +68,7 @@ public class MethodReference extends SpelNodeImpl {
|
||||||
throwIfNotNullSafe(getArgumentTypes(arguments));
|
throwIfNotNullSafe(getArgumentTypes(arguments));
|
||||||
return ValueRef.NullValueRef.instance;
|
return ValueRef.NullValueRef.instance;
|
||||||
}
|
}
|
||||||
return new MethodValueRef(state);
|
return new MethodValueRef(state, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -246,11 +246,11 @@ public class MethodReference extends SpelNodeImpl {
|
||||||
|
|
||||||
private final Object[] arguments;
|
private final Object[] arguments;
|
||||||
|
|
||||||
public MethodValueRef(ExpressionState state) {
|
public MethodValueRef(ExpressionState state, Object[] arguments) {
|
||||||
this.evaluationContext = state.getEvaluationContext();
|
this.evaluationContext = state.getEvaluationContext();
|
||||||
this.value = state.getActiveContextObject().getValue();
|
this.value = state.getActiveContextObject().getValue();
|
||||||
this.targetType = state.getActiveContextObject().getTypeDescriptor();
|
this.targetType = state.getActiveContextObject().getTypeDescriptor();
|
||||||
this.arguments = getArguments(state);
|
this.arguments = arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -1825,6 +1826,39 @@ public class SpelReproTests extends AbstractExpressionTests {
|
||||||
assertEquals("two", list.get(1));
|
assertEquals("two", list.get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void SPR11494() {
|
public void SPR11494() {
|
||||||
Expression exp = new SpelExpressionParser().parseExpression("T(java.util.Arrays).asList('a','b')");
|
Expression exp = new SpelExpressionParser().parseExpression("T(java.util.Arrays).asList('a','b')");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue