Skip to content

Commit 15c5cf4

Browse files
committed
Merge branch '6.2.x'
2 parents 86fb62c + 0e3e34b commit 15c5cf4

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

spring-core/src/main/java/org/springframework/core/annotation/AnnotatedMethod.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.lang.annotation.Annotation;
2020
import java.lang.reflect.Method;
21+
import java.lang.reflect.Modifier;
2122
import java.util.ArrayList;
2223
import java.util.Arrays;
2324
import java.util.List;
@@ -38,6 +39,7 @@
3839
* interface-declared parameter annotations from the concrete target method.
3940
*
4041
* @author Juergen Hoeller
42+
* @author Sam Brannen
4143
* @since 6.1
4244
* @see #getMethodAnnotation(Class)
4345
* @see #getMethodParameters()
@@ -179,7 +181,7 @@ private List<Annotation[][]> getInheritedParameterAnnotations() {
179181
clazz = null;
180182
}
181183
if (clazz != null) {
182-
for (Method candidate : clazz.getMethods()) {
184+
for (Method candidate : clazz.getDeclaredMethods()) {
183185
if (isOverrideFor(candidate)) {
184186
parameterAnnotations.add(candidate.getParameterAnnotations());
185187
}
@@ -192,8 +194,9 @@ private List<Annotation[][]> getInheritedParameterAnnotations() {
192194
}
193195

194196
private boolean isOverrideFor(Method candidate) {
195-
if (!candidate.getName().equals(this.method.getName()) ||
196-
candidate.getParameterCount() != this.method.getParameterCount()) {
197+
if (Modifier.isPrivate(candidate.getModifiers()) ||
198+
!candidate.getName().equals(this.method.getName()) ||
199+
(candidate.getParameterCount() != this.method.getParameterCount())) {
197200
return false;
198201
}
199202
Class<?>[] paramTypes = this.method.getParameterTypes();

spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,14 @@ private static boolean hasSameParameterTypes(Method rootMethod, Method candidate
367367
private static boolean hasSameGenericTypeParameters(
368368
Method rootMethod, Method candidateMethod, Class<?>[] rootParameterTypes) {
369369

370-
Class<?> sourceDeclaringClass = rootMethod.getDeclaringClass();
370+
Class<?> rootDeclaringClass = rootMethod.getDeclaringClass();
371371
Class<?> candidateDeclaringClass = candidateMethod.getDeclaringClass();
372-
if (!candidateDeclaringClass.isAssignableFrom(sourceDeclaringClass)) {
372+
if (!candidateDeclaringClass.isAssignableFrom(rootDeclaringClass)) {
373373
return false;
374374
}
375375
for (int i = 0; i < rootParameterTypes.length; i++) {
376376
Class<?> resolvedParameterType = ResolvableType.forMethodParameter(
377-
candidateMethod, i, sourceDeclaringClass).toClass();
377+
candidateMethod, i, rootDeclaringClass).toClass();
378378
if (rootParameterTypes[i] != resolvedParameterType) {
379379
return false;
380380
}

spring-core/src/test/java/org/springframework/core/annotation/AnnotatedMethodTests.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.RetentionPolicy;
2121
import java.lang.reflect.Method;
22+
import java.lang.reflect.Modifier;
2223

2324
import org.junit.jupiter.api.Test;
2425

2526
import org.springframework.core.MethodParameter;
26-
import org.springframework.util.ClassUtils;
27+
import org.springframework.util.ReflectionUtils;
2728

29+
import static java.util.Arrays.stream;
30+
import static java.util.stream.Collectors.joining;
2831
import static org.assertj.core.api.Assertions.assertThat;
2932

3033
/**
@@ -55,6 +58,12 @@ void shouldFindAnnotationOnMethodInGenericInterface() {
5558

5659
@Test
5760
void shouldFindAnnotationOnMethodParameterInGenericAbstractSuperclass() {
61+
// Prerequisites for gh-35349
62+
Method abstractMethod = ReflectionUtils.findMethod(GenericAbstractSuperclass.class, "processTwo", Object.class);
63+
assertThat(abstractMethod).isNotNull();
64+
assertThat(Modifier.isAbstract(abstractMethod.getModifiers())).as("abstract").isTrue();
65+
assertThat(Modifier.isPublic(abstractMethod.getModifiers())).as("public").isFalse();
66+
5867
Method processTwo = getMethod("processTwo", String.class);
5968

6069
AnnotatedMethod annotatedMethod = new AnnotatedMethod(processTwo);
@@ -78,7 +87,14 @@ void shouldFindAnnotationOnMethodParameterInGenericInterface() {
7887

7988

8089
private static Method getMethod(String name, Class<?>...parameterTypes) {
81-
return ClassUtils.getMethod(GenericInterfaceImpl.class, name, parameterTypes);
90+
Class<?> clazz = GenericInterfaceImpl.class;
91+
Method method = ReflectionUtils.findMethod(clazz, name, parameterTypes);
92+
if (method == null) {
93+
String parameterNames = stream(parameterTypes).map(Class::getName).collect(joining(", "));
94+
throw new IllegalStateException("Expected method not found: %s#%s(%s)"
95+
.formatted(clazz.getSimpleName(), name, parameterNames));
96+
}
97+
return method;
8298
}
8399

84100

@@ -103,13 +119,14 @@ public void processOneAndTwo(Long value1, C value2) {
103119
}
104120

105121
@Handler
106-
public abstract void processTwo(@Param C value);
122+
// Intentionally NOT public
123+
abstract void processTwo(@Param C value);
107124
}
108125

109126
static class GenericInterfaceImpl extends GenericAbstractSuperclass<String> {
110127

111128
@Override
112-
public void processTwo(String value) {
129+
void processTwo(String value) {
113130
}
114131
}
115132

0 commit comments

Comments
 (0)