Skip to content

Commit

Permalink
Add fast path for ClassUtils.hasMethod()
Browse files Browse the repository at this point in the history
  • Loading branch information
stsypanov authored and jhoeller committed Jan 8, 2020
1 parent c562c3a commit 8e5cad2
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 12 deletions.
Expand Up @@ -365,7 +365,7 @@ public int hashCode() {
*/
private static boolean implementsInterface(Method method, Set<Class<?>> ifcs) {
for (Class<?> ifc : ifcs) {
if (ClassUtils.hasMethod(ifc, method.getName(), method.getParameterTypes())) {
if (ClassUtils.hasMethod(ifc, method)) {
return true;
}
}
Expand Down
Expand Up @@ -97,7 +97,7 @@ public static boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
// It was declared by CGLIB, but we might still want to autowire it
// if it was actually declared by the superclass.
Class<?> superclass = wm.getDeclaringClass().getSuperclass();
return !ClassUtils.hasMethod(superclass, wm.getName(), wm.getParameterTypes());
return !ClassUtils.hasMethod(superclass, wm);
}

/**
Expand All @@ -112,8 +112,7 @@ public static boolean isSetterDefinedInInterface(PropertyDescriptor pd, Set<Clas
if (setter != null) {
Class<?> targetClass = setter.getDeclaringClass();
for (Class<?> ifc : interfaces) {
if (ifc.isAssignableFrom(targetClass) &&
ClassUtils.hasMethod(ifc, setter.getName(), setter.getParameterTypes())) {
if (ifc.isAssignableFrom(targetClass) && ClassUtils.hasMethod(ifc, setter)) {
return true;
}
}
Expand Down
Expand Up @@ -207,7 +207,7 @@ protected boolean includeOperation(Method method, String beanKey) {
* configured interfaces and is public, otherwise {@code false}.
*/
private boolean isPublicInInterface(Method method, String beanKey) {
return ((method.getModifiers() & Modifier.PUBLIC) > 0) && isDeclaredInInterface(method, beanKey);
return Modifier.isPublic(method.getModifiers()) && isDeclaredInInterface(method, beanKey);
}

/**
Expand Down
Expand Up @@ -145,7 +145,7 @@ else if (FactoryBean.class.isAssignableFrom(clazz)) {
factoryBeanType = FactoryBean.class;
}
return (factoryBeanType != null && !method.getName().equals("getObject") &&
ClassUtils.hasMethod(factoryBeanType, method.getName(), method.getParameterTypes()));
ClassUtils.hasMethod(factoryBeanType, method));
}

/**
Expand Down
34 changes: 28 additions & 6 deletions spring-core/src/main/java/org/springframework/util/ClassUtils.java
Expand Up @@ -1101,6 +1101,24 @@ public static boolean hasMethod(Class<?> clazz, String methodName, Class<?>... p
return (getMethodIfAvailable(clazz, methodName, paramTypes) != null);
}

/**
* Determine whether the given class has a public method with the given signature.
* @param clazz the clazz to analyze
* @param method checked method
* @return whether the class has a corresponding method
* @see Method#getDeclaringClass
*/
public static boolean hasMethod(Class<?> clazz, Method method) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(method, "Method must not be null");
if (clazz == method.getDeclaringClass()) {
return true;
}
String methodName = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
return getMethodOrNull(clazz, methodName, paramTypes) != null;
}

/**
* Determine whether the given class has a public method with the given signature,
* and return it if available (else throws an {@code IllegalStateException}).
Expand Down Expand Up @@ -1158,12 +1176,7 @@ public static Method getMethodIfAvailable(Class<?> clazz, String methodName, @Nu
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(methodName, "Method name must not be null");
if (paramTypes != null) {
try {
return clazz.getMethod(methodName, paramTypes);
}
catch (NoSuchMethodException ex) {
return null;
}
return getMethodOrNull(clazz, methodName, paramTypes);
}
else {
Set<Method> candidates = findMethodCandidatesByName(clazz, methodName);
Expand Down Expand Up @@ -1370,4 +1383,13 @@ private static Set<Method> findMethodCandidatesByName(Class<?> clazz, String met
}
return candidates;
}

@Nullable
private static Method getMethodOrNull(Class<?> clazz, String methodName, Class<?>[] paramTypes) {
try {
return clazz.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException ex) {
return null;
}
}
}

0 comments on commit 8e5cad2

Please sign in to comment.