Browse Source

Filter candidate methods by name first (for more efficient sorting)

Closes gh-28377
pull/31694/head
Juergen Hoeller 2 years ago
parent
commit
0599320bd8
  1. 71
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java

71
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java

@ -117,6 +117,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
TypeConverter typeConverter = context.getTypeConverter(); TypeConverter typeConverter = context.getTypeConverter();
Class<?> type = (targetObject instanceof Class<?> clazz ? clazz : targetObject.getClass()); Class<?> type = (targetObject instanceof Class<?> clazz ? clazz : targetObject.getClass());
ArrayList<Method> methods = new ArrayList<>(getMethods(type, targetObject)); ArrayList<Method> methods = new ArrayList<>(getMethods(type, targetObject));
methods.removeIf(method -> !method.getName().equals(name));
// 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);
@ -160,48 +161,46 @@ public class ReflectiveMethodResolver implements MethodResolver {
boolean multipleOptions = false; boolean multipleOptions = false;
for (Method method : methodsToIterate) { for (Method method : methodsToIterate) {
if (method.getName().equals(name)) { int paramCount = method.getParameterCount();
int paramCount = method.getParameterCount(); List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramCount);
List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramCount); for (int i = 0; i < paramCount; i++) {
for (int i = 0; i < paramCount; i++) { paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i))); }
} ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
ReflectionHelper.ArgumentsMatchInfo matchInfo = null; if (method.isVarArgs() && argumentTypes.size() >= (paramCount - 1)) {
if (method.isVarArgs() && argumentTypes.size() >= (paramCount - 1)) { // *sigh* complicated
// *sigh* complicated matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); }
} else if (paramCount == argumentTypes.size()) {
else if (paramCount == argumentTypes.size()) { // Name and parameter number match, check the arguments
// Name and parameter number match, check the arguments matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); }
if (matchInfo != null) {
if (matchInfo.isExactMatch()) {
return new ReflectiveMethodExecutor(method, type);
} }
if (matchInfo != null) { else if (matchInfo.isCloseMatch()) {
if (matchInfo.isExactMatch()) { if (this.useDistance) {
return new ReflectiveMethodExecutor(method, type); int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
} if (closeMatch == null || matchDistance < closeMatchDistance) {
else if (matchInfo.isCloseMatch()) { // This is a better match...
if (this.useDistance) { closeMatch = method;
int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes); closeMatchDistance = matchDistance;
if (closeMatch == null || matchDistance < closeMatchDistance) {
// This is a better match...
closeMatch = method;
closeMatchDistance = matchDistance;
}
}
else {
// Take this as a close match if there isn't one already
if (closeMatch == null) {
closeMatch = method;
}
} }
} }
else if (matchInfo.isMatchRequiringConversion()) { else {
if (matchRequiringConversion != null) { // Take this as a close match if there isn't one already
multipleOptions = true; if (closeMatch == null) {
closeMatch = method;
} }
matchRequiringConversion = method;
} }
} }
else if (matchInfo.isMatchRequiringConversion()) {
if (matchRequiringConversion != null) {
multipleOptions = true;
}
matchRequiringConversion = method;
}
} }
} }
if (closeMatch != null) { if (closeMatch != null) {

Loading…
Cancel
Save