Skip to content

Commit 182da15

Browse files
committed
BridgeMethodResolver properly resolves interface hierarchies
Issue: SPR-16103
1 parent 55b0c2f commit 182da15

File tree

2 files changed

+160
-91
lines changed

2 files changed

+160
-91
lines changed

spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -138,43 +138,13 @@ static boolean isBridgeMethodFor(Method bridgeMethod, Method candidateMethod, Cl
138138
return (method != null && isResolvedTypeMatch(method, candidateMethod, declaringClass));
139139
}
140140

141-
/**
142-
* Searches for the generic {@link Method} declaration whose erased signature
143-
* matches that of the supplied bridge method.
144-
* @throws IllegalStateException if the generic declaration cannot be found
145-
*/
146-
@Nullable
147-
private static Method findGenericDeclaration(Method bridgeMethod) {
148-
// Search parent types for method that has same signature as bridge.
149-
Class<?> superclass = bridgeMethod.getDeclaringClass().getSuperclass();
150-
while (superclass != null && Object.class != superclass) {
151-
Method method = searchForMatch(superclass, bridgeMethod);
152-
if (method != null && !method.isBridge()) {
153-
return method;
154-
}
155-
superclass = superclass.getSuperclass();
156-
}
157-
158-
// Search interfaces.
159-
Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(bridgeMethod.getDeclaringClass());
160-
for (Class<?> ifc : interfaces) {
161-
Method method = searchForMatch(ifc, bridgeMethod);
162-
if (method != null && !method.isBridge()) {
163-
return method;
164-
}
165-
}
166-
167-
return null;
168-
}
169-
170141
/**
171142
* Returns {@code true} if the {@link Type} signature of both the supplied
172143
* {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method}
173144
* are equal after resolving all types against the declaringType, otherwise
174145
* returns {@code false}.
175146
*/
176-
private static boolean isResolvedTypeMatch(
177-
Method genericMethod, Method candidateMethod, Class<?> declaringClass) {
147+
private static boolean isResolvedTypeMatch(Method genericMethod, Method candidateMethod, Class<?> declaringClass) {
178148
Type[] genericParameters = genericMethod.getGenericParameterTypes();
179149
Class<?>[] candidateParameters = candidateMethod.getParameterTypes();
180150
if (genericParameters.length != candidateParameters.length) {
@@ -197,14 +167,54 @@ private static boolean isResolvedTypeMatch(
197167
return true;
198168
}
199169

170+
/**
171+
* Searches for the generic {@link Method} declaration whose erased signature
172+
* matches that of the supplied bridge method.
173+
* @throws IllegalStateException if the generic declaration cannot be found
174+
*/
175+
@Nullable
176+
private static Method findGenericDeclaration(Method bridgeMethod) {
177+
// Search parent types for method that has same signature as bridge.
178+
Class<?> superclass = bridgeMethod.getDeclaringClass().getSuperclass();
179+
while (superclass != null && Object.class != superclass) {
180+
Method method = searchForMatch(superclass, bridgeMethod);
181+
if (method != null && !method.isBridge()) {
182+
return method;
183+
}
184+
superclass = superclass.getSuperclass();
185+
}
186+
187+
Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(bridgeMethod.getDeclaringClass());
188+
return searchInterfaces(interfaces, bridgeMethod);
189+
}
190+
191+
@Nullable
192+
private static Method searchInterfaces(Class<?>[] interfaces, Method bridgeMethod) {
193+
for (Class<?> ifc : interfaces) {
194+
Method method = searchForMatch(ifc, bridgeMethod);
195+
if (method != null && !method.isBridge()) {
196+
return method;
197+
}
198+
else {
199+
return searchInterfaces(ifc.getInterfaces(), bridgeMethod);
200+
}
201+
}
202+
return null;
203+
}
204+
200205
/**
201206
* If the supplied {@link Class} has a declared {@link Method} whose signature matches
202207
* that of the supplied {@link Method}, then this matching {@link Method} is returned,
203208
* otherwise {@code null} is returned.
204209
*/
205210
@Nullable
206211
private static Method searchForMatch(Class<?> type, Method bridgeMethod) {
207-
return ReflectionUtils.findMethod(type, bridgeMethod.getName(), bridgeMethod.getParameterTypes());
212+
try {
213+
return type.getDeclaredMethod(bridgeMethod.getName(), bridgeMethod.getParameterTypes());
214+
}
215+
catch (NoSuchMethodException ex) {
216+
return null;
217+
}
208218
}
209219

210220
/**

0 commit comments

Comments
 (0)