diff --git a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java index 36a1e328822..25456406898 100644 --- a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java +++ b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java @@ -21,10 +21,13 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; +import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; +import org.springframework.util.ReflectionUtils.MethodFilter; /** * Helper for resolving synthetic {@link Method#isBridge bridge Methods} to the @@ -47,6 +50,8 @@ import org.springframework.util.ReflectionUtils; */ public final class BridgeMethodResolver { + private static final Map cache = new ConcurrentReferenceHashMap<>(); + private BridgeMethodResolver() { } @@ -64,32 +69,26 @@ public final class BridgeMethodResolver { if (!bridgeMethod.isBridge()) { return bridgeMethod; } - - // Gather all methods with matching name and parameter size. - List candidateMethods = new ArrayList<>(); - Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass()); - for (Method candidateMethod : methods) { - if (isBridgedCandidateFor(candidateMethod, bridgeMethod)) { - candidateMethods.add(candidateMethod); + Method bridgedMethod = cache.get(bridgeMethod); + if (bridgedMethod == null) { + // Gather all methods with matching name and parameter size. + List candidateMethods = new ArrayList<>(); + MethodFilter filter = candidateMethod -> + isBridgedCandidateFor(candidateMethod, bridgeMethod); + ReflectionUtils.doWithMethods(bridgeMethod.getDeclaringClass(), candidateMethods::add, filter); + if (!candidateMethods.isEmpty()) { + bridgedMethod = candidateMethods.size() == 1 ? + candidateMethods.get(0) : + searchCandidates(candidateMethods, bridgeMethod); } + if (bridgedMethod == null) { + // A bridge method was passed in but we couldn't find the bridged method. + // Let's proceed with the passed-in method and hope for the best... + bridgedMethod = bridgeMethod; + } + cache.put(bridgeMethod, bridgedMethod); } - - // Now perform simple quick check. - if (candidateMethods.size() == 1) { - return candidateMethods.get(0); - } - - // Search for candidate match. - Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod); - if (bridgedMethod != null) { - // Bridged method found... - return bridgedMethod; - } - else { - // A bridge method was passed in but we couldn't find the bridged method. - // Let's proceed with the passed-in method and hope for the best... - return bridgeMethod; - } + return bridgedMethod; } /**