Revised ReflectiveMethodResolver to properly handle any kind of List returned from a MethodFilter
Issue: SPR-10392
This commit is contained in:
parent
35847ad003
commit
ad886503f1
|
@ -42,8 +42,8 @@ import org.springframework.expression.spel.SpelEvaluationException;
|
||||||
import org.springframework.expression.spel.SpelMessage;
|
import org.springframework.expression.spel.SpelMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflection-based {@link MethodResolver} used by default in
|
* Reflection-based {@link MethodResolver} used by default in {@link StandardEvaluationContext}
|
||||||
* {@link StandardEvaluationContext} unless explicit method resolvers have been specified.
|
* unless explicit method resolvers have been specified.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -63,7 +63,6 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
|
|
||||||
|
|
||||||
public ReflectiveMethodResolver() {
|
public ReflectiveMethodResolver() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +98,8 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
// If a filter is registered for this type, call it
|
// If a filter is registered for this type, call it
|
||||||
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
|
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
methods = filter.filter(methods);
|
List<Method> filtered = filter.filter(methods);
|
||||||
|
methods = (filtered instanceof ArrayList ? filtered : new ArrayList<Method>(filtered));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort methods into a sensible order
|
// Sort methods into a sensible order
|
||||||
|
@ -119,7 +119,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicate methods (possible due to resolved bridge methods)
|
// Remove duplicate methods (possible due to resolved bridge methods)
|
||||||
methods = new ArrayList<Method>(new LinkedHashSet<Method>(methods));
|
Set<Method> methodsToIterate = new LinkedHashSet<Method>(methods);
|
||||||
|
|
||||||
Method closeMatch = null;
|
Method closeMatch = null;
|
||||||
int closeMatchDistance = Integer.MAX_VALUE;
|
int closeMatchDistance = Integer.MAX_VALUE;
|
||||||
|
@ -127,7 +127,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
Method matchRequiringConversion = null;
|
Method matchRequiringConversion = null;
|
||||||
boolean multipleOptions = false;
|
boolean multipleOptions = false;
|
||||||
|
|
||||||
for (Method method : methods) {
|
for (Method method : methodsToIterate) {
|
||||||
if (method.getName().equals(name)) {
|
if (method.getName().equals(name)) {
|
||||||
Class<?>[] paramTypes = method.getParameterTypes();
|
Class<?>[] paramTypes = method.getParameterTypes();
|
||||||
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
|
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
|
||||||
|
@ -148,9 +148,10 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
return new ReflectiveMethodExecutor(method, null);
|
return new ReflectiveMethodExecutor(method, null);
|
||||||
}
|
}
|
||||||
else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) {
|
else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) {
|
||||||
if (!useDistance) {
|
if (!this.useDistance) {
|
||||||
closeMatch = method;
|
closeMatch = method;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
|
int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
|
||||||
if (matchDistance<closeMatchDistance) {
|
if (matchDistance<closeMatchDistance) {
|
||||||
// this is a better match
|
// this is a better match
|
||||||
|
@ -200,7 +201,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method[] getMethods(Class<?> type, Object targetObject) {
|
private Method[] getMethods(Class<?> type, Object targetObject) {
|
||||||
if(targetObject instanceof Class) {
|
if (targetObject instanceof Class) {
|
||||||
Set<Method> methods = new HashSet<Method>();
|
Set<Method> methods = new HashSet<Method>();
|
||||||
methods.addAll(Arrays.asList(getMethods(type)));
|
methods.addAll(Arrays.asList(getMethods(type)));
|
||||||
methods.addAll(Arrays.asList(getMethods(targetObject.getClass())));
|
methods.addAll(Arrays.asList(getMethods(targetObject.getClass())));
|
||||||
|
@ -211,9 +212,9 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the set of methods for this type. The default implementation returns the
|
* Return the set of methods for this type. The default implementation returns the
|
||||||
* result of Class#getMethods for the given {@code type}, but subclasses may override
|
* result of {@link Class#getMethods()} for the given {@code type}, but subclasses
|
||||||
* in order to alter the results, e.g. specifying static methods declared elsewhere.
|
* may override in order to alter the results, e.g. specifying static methods
|
||||||
*
|
* declared elsewhere.
|
||||||
* @param type the class for which to return the methods
|
* @param type the class for which to return the methods
|
||||||
* @since 3.1.1
|
* @since 3.1.1
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue