Scan annotations on method in interface hierarchy only once
Prior to this commit, the AnnotationsScanner used in the
MergedAnnotations infrastructure found duplicate annotations on methods
within multi-level interface hierarchies.
This commit addresses this issue by scanning methods at a given level
in the interface hierarchy using ReflectionUtils#getDeclaredMethods
instead of Class#getMethods, since the latter includes public methods
declared in super-interfaces which will anyway be scanned when
processing super-interfaces recursively.
Closes gh-31803
(cherry picked from commit 75da9c3c47)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -357,6 +357,15 @@ class AnnotationsScannerTests {
|
||||
Method source = methodFrom(WithSingleInterface.class);
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY)).containsExactly(
|
||||
"0:TestAnnotation1", "1:TestAnnotation2", "1:TestInheritedAnnotation2");
|
||||
|
||||
source = methodFrom(Hello1Impl.class);
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY)).containsExactly("1:TestAnnotation1");
|
||||
}
|
||||
|
||||
@Test // gh-31803
|
||||
void typeHierarchyStrategyOnMethodWhenHasInterfaceHierarchyScansInterfacesOnlyOnce() {
|
||||
Method source = methodFrom(Hello2Impl.class);
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY)).containsExactly("1:TestAnnotation1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -691,6 +700,30 @@ class AnnotationsScannerTests {
|
||||
}
|
||||
}
|
||||
|
||||
interface Hello1 {
|
||||
|
||||
@TestAnnotation1
|
||||
void method();
|
||||
}
|
||||
|
||||
interface Hello2 extends Hello1 {
|
||||
}
|
||||
|
||||
static class Hello1Impl implements Hello1 {
|
||||
|
||||
@Override
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
static class Hello2Impl implements Hello2 {
|
||||
|
||||
@Override
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@TestAnnotation2
|
||||
@TestInheritedAnnotation2
|
||||
static class HierarchySuperclass extends HierarchySuperSuperclass {
|
||||
|
||||
@@ -40,6 +40,8 @@ import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationsScannerTests.Hello2Impl;
|
||||
import org.springframework.core.annotation.AnnotationsScannerTests.TestAnnotation1;
|
||||
import org.springframework.core.annotation.MergedAnnotation.Adapt;
|
||||
import org.springframework.core.annotation.MergedAnnotations.Search;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
@@ -686,6 +688,16 @@ class MergedAnnotationsTests {
|
||||
assertThat(annotation.getAggregateIndex()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test // gh-31803
|
||||
void streamWithTypeHierarchyInheritedFromSuperInterfaceMethod() throws Exception {
|
||||
Method method = Hello2Impl.class.getMethod("method");
|
||||
long count = MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
|
||||
.from(method)
|
||||
.stream(TestAnnotation1.class)
|
||||
.count();
|
||||
assertThat(count).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWithTypeHierarchyInheritedFromAbstractMethod() throws NoSuchMethodException {
|
||||
Method method = ConcreteClassWithInheritedAnnotation.class.getMethod("handle");
|
||||
|
||||
Reference in New Issue
Block a user