Browse Source

Merge branch '6.2.x'

pull/35428/head
Sam Brannen 3 months ago
parent
commit
15c5cf472b
  1. 9
      spring-core/src/main/java/org/springframework/core/annotation/AnnotatedMethod.java
  2. 6
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationsScanner.java
  3. 25
      spring-core/src/test/java/org/springframework/core/annotation/AnnotatedMethodTests.java

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

@ -18,6 +18,7 @@ package org.springframework.core.annotation; @@ -18,6 +18,7 @@ package org.springframework.core.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -38,6 +39,7 @@ import org.springframework.util.StringUtils; @@ -38,6 +39,7 @@ import org.springframework.util.StringUtils;
* interface-declared parameter annotations from the concrete target method.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 6.1
* @see #getMethodAnnotation(Class)
* @see #getMethodParameters()
@ -179,7 +181,7 @@ public class AnnotatedMethod { @@ -179,7 +181,7 @@ public class AnnotatedMethod {
clazz = null;
}
if (clazz != null) {
for (Method candidate : clazz.getMethods()) {
for (Method candidate : clazz.getDeclaredMethods()) {
if (isOverrideFor(candidate)) {
parameterAnnotations.add(candidate.getParameterAnnotations());
}
@ -192,8 +194,9 @@ public class AnnotatedMethod { @@ -192,8 +194,9 @@ public class AnnotatedMethod {
}
private boolean isOverrideFor(Method candidate) {
if (!candidate.getName().equals(this.method.getName()) ||
candidate.getParameterCount() != this.method.getParameterCount()) {
if (Modifier.isPrivate(candidate.getModifiers()) ||
!candidate.getName().equals(this.method.getName()) ||
(candidate.getParameterCount() != this.method.getParameterCount())) {
return false;
}
Class<?>[] paramTypes = this.method.getParameterTypes();

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

@ -367,14 +367,14 @@ abstract class AnnotationsScanner { @@ -367,14 +367,14 @@ abstract class AnnotationsScanner {
private static boolean hasSameGenericTypeParameters(
Method rootMethod, Method candidateMethod, Class<?>[] rootParameterTypes) {
Class<?> sourceDeclaringClass = rootMethod.getDeclaringClass();
Class<?> rootDeclaringClass = rootMethod.getDeclaringClass();
Class<?> candidateDeclaringClass = candidateMethod.getDeclaringClass();
if (!candidateDeclaringClass.isAssignableFrom(sourceDeclaringClass)) {
if (!candidateDeclaringClass.isAssignableFrom(rootDeclaringClass)) {
return false;
}
for (int i = 0; i < rootParameterTypes.length; i++) {
Class<?> resolvedParameterType = ResolvableType.forMethodParameter(
candidateMethod, i, sourceDeclaringClass).toClass();
candidateMethod, i, rootDeclaringClass).toClass();
if (rootParameterTypes[i] != resolvedParameterType) {
return false;
}

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

@ -19,12 +19,15 @@ package org.springframework.core.annotation; @@ -19,12 +19,15 @@ package org.springframework.core.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -55,6 +58,12 @@ class AnnotatedMethodTests { @@ -55,6 +58,12 @@ class AnnotatedMethodTests {
@Test
void shouldFindAnnotationOnMethodParameterInGenericAbstractSuperclass() {
// Prerequisites for gh-35349
Method abstractMethod = ReflectionUtils.findMethod(GenericAbstractSuperclass.class, "processTwo", Object.class);
assertThat(abstractMethod).isNotNull();
assertThat(Modifier.isAbstract(abstractMethod.getModifiers())).as("abstract").isTrue();
assertThat(Modifier.isPublic(abstractMethod.getModifiers())).as("public").isFalse();
Method processTwo = getMethod("processTwo", String.class);
AnnotatedMethod annotatedMethod = new AnnotatedMethod(processTwo);
@ -78,7 +87,14 @@ class AnnotatedMethodTests { @@ -78,7 +87,14 @@ class AnnotatedMethodTests {
private static Method getMethod(String name, Class<?>...parameterTypes) {
return ClassUtils.getMethod(GenericInterfaceImpl.class, name, parameterTypes);
Class<?> clazz = GenericInterfaceImpl.class;
Method method = ReflectionUtils.findMethod(clazz, name, parameterTypes);
if (method == null) {
String parameterNames = stream(parameterTypes).map(Class::getName).collect(joining(", "));
throw new IllegalStateException("Expected method not found: %s#%s(%s)"
.formatted(clazz.getSimpleName(), name, parameterNames));
}
return method;
}
@ -103,13 +119,14 @@ class AnnotatedMethodTests { @@ -103,13 +119,14 @@ class AnnotatedMethodTests {
}
@Handler
public abstract void processTwo(@Param C value);
// Intentionally NOT public
abstract void processTwo(@Param C value);
}
static class GenericInterfaceImpl extends GenericAbstractSuperclass<String> {
@Override
public void processTwo(String value) {
void processTwo(String value) {
}
}

Loading…
Cancel
Save