diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index c1055e5fddc..552e23b8511 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -22,8 +22,11 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.MethodParameter; @@ -50,6 +53,17 @@ import org.springframework.util.StringUtils; */ public class ReflectivePropertyAccessor implements PropertyAccessor { + private static final Set> BOOLEAN_TYPES; + static { + Set> booleanTypes = new HashSet>(); + booleanTypes.add(Boolean.class); + booleanTypes.add(Boolean.TYPE); + BOOLEAN_TYPES = Collections.unmodifiableSet(booleanTypes); + } + + private static final Set> ANY_TYPES = Collections.emptySet(); + + private final Map readerCache = new ConcurrentHashMap(64); private final Map writerCache = new ConcurrentHashMap(64); @@ -314,8 +328,13 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { * Find a getter method for the specified property. */ protected Method findGetterForProperty(String propertyName, Class clazz, boolean mustBeStatic) { - return findMethodForProperty(getPropertyMethodSuffixes(propertyName), - new String[] { "get", "is" }, clazz, mustBeStatic, 0); + Method method = findMethodForProperty(getPropertyMethodSuffixes(propertyName), + "get", clazz, mustBeStatic, 0, ANY_TYPES); + if (method == null) { + method = findMethodForProperty(getPropertyMethodSuffixes(propertyName), + "is", clazz, mustBeStatic, 0, BOOLEAN_TYPES); + } + return method; } /** @@ -323,20 +342,19 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { */ protected Method findSetterForProperty(String propertyName, Class clazz, boolean mustBeStatic) { return findMethodForProperty(getPropertyMethodSuffixes(propertyName), - new String[] { "set" }, clazz, mustBeStatic, 1); + "set", clazz, mustBeStatic, 1, ANY_TYPES); } - private Method findMethodForProperty(String[] methodSuffixes, String[] prefixes, Class clazz, - boolean mustBeStatic, int numberOfParams) { + private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class clazz, + boolean mustBeStatic, int numberOfParams, Set> requiredReturnTypes) { Method[] methods = getSortedClassMethods(clazz); for (String methodSuffix : methodSuffixes) { - for (String prefix : prefixes) { - for (Method method : methods) { - if (method.getName().equals(prefix + methodSuffix) - && method.getParameterTypes().length == numberOfParams - && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { - return method; - } + for (Method method : methods) { + if (method.getName().equals(prefix + methodSuffix) + && method.getParameterTypes().length == numberOfParams + && (!mustBeStatic || Modifier.isStatic(method.getModifiers())) + && (requiredReturnTypes.isEmpty() || requiredReturnTypes.contains(method.getReturnType()))) { + return method; } } } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java index 28c7570b947..c6957f862be 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java @@ -1831,6 +1831,17 @@ public class SpelReproTests extends ExpressionTestCase { equalTo((Object) "name")); } + @Test + public void SPR_11142() throws Exception { + SpelExpressionParser parser = new SpelExpressionParser(); + StandardEvaluationContext context = new StandardEvaluationContext(); + SPR11142 rootObject = new SPR11142(); + Expression expression = parser.parseExpression("something"); + thrown.expect(SpelEvaluationException.class); + thrown.expectMessage("property 'something' cannot be found"); + expression.getValue(context, rootObject); + } + private static enum ABC {A, B, C} @@ -1914,4 +1925,12 @@ public class SpelReproTests extends ExpressionTestCase { } } + + static class SPR11142 { + + public String isSomething() { + return ""; + } + + } }