Skip to content

Commit

Permalink
ConcurrentReferenceHashMap cache for getInterfaceMethodIfPossible res…
Browse files Browse the repository at this point in the history
…ults

Closes gh-24206
  • Loading branch information
jhoeller committed Dec 16, 2019
1 parent 5836680 commit f353bc0
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions spring-core/src/main/java/org/springframework/util/ClassUtils.java
Expand Up @@ -111,6 +111,11 @@ public abstract class ClassUtils {
*/
private static final Set<Class<?>> javaLanguageInterfaces;

/**
* Cache for equivalent methods on an interface implemented by the declaring class.
*/
private static final Map<Method, Method> interfaceMethodCache = new ConcurrentReferenceHashMap<>(256);


static {
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
Expand Down Expand Up @@ -1277,22 +1282,25 @@ public static Method getMostSpecificMethod(Method method, @Nullable Class<?> tar
* @see #getMostSpecificMethod
*/
public static Method getInterfaceMethodIfPossible(Method method) {
if (Modifier.isPublic(method.getModifiers()) && !method.getDeclaringClass().isInterface()) {
Class<?> current = method.getDeclaringClass();
if (!Modifier.isPublic(method.getModifiers()) || method.getDeclaringClass().isInterface()) {
return method;
}
return interfaceMethodCache.computeIfAbsent(method, key -> {
Class<?> current = key.getDeclaringClass();
while (current != null && current != Object.class) {
Class<?>[] ifcs = current.getInterfaces();
for (Class<?> ifc : ifcs) {
try {
return ifc.getMethod(method.getName(), method.getParameterTypes());
return ifc.getMethod(key.getName(), key.getParameterTypes());
}
catch (NoSuchMethodException ex) {
// ignore
}
}
current = current.getSuperclass();
}
}
return method;
return key;
});
}

/**
Expand Down

0 comments on commit f353bc0

Please sign in to comment.