Skip to content

Commit fd8fa30

Browse files
committed
Consistent non-exposure of inherited annotations in AnnotationMetadata
Closes gh-22766
1 parent 2e7ed91 commit fd8fa30

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -638,13 +638,13 @@ private SourceClass asSourceClass(ConfigurationClass configurationClass) throws
638638
* Factory method to obtain a {@link SourceClass} from a {@link Class}.
639639
*/
640640
SourceClass asSourceClass(@Nullable Class<?> classType) throws IOException {
641-
if (classType == null || classType.getName().startsWith("java.lang.annotation")) {
641+
if (classType == null || classType.getName().startsWith("java.lang.annotation.")) {
642642
return this.objectSourceClass;
643643
}
644644
try {
645645
// Sanity test that we can reflectively read annotations,
646646
// including Class attributes; if not -> fall back to ASM
647-
for (Annotation ann : classType.getAnnotations()) {
647+
for (Annotation ann : classType.getDeclaredAnnotations()) {
648648
AnnotationUtils.validateAnnotation(ann);
649649
}
650650
return new SourceClass(classType);
@@ -670,7 +670,7 @@ private Collection<SourceClass> asSourceClasses(String... classNames) throws IOE
670670
* Factory method to obtain a {@link SourceClass} from a class name.
671671
*/
672672
SourceClass asSourceClass(@Nullable String className) throws IOException {
673-
if (className == null || className.startsWith("java.lang.annotation")) {
673+
if (className == null || className.startsWith("java.lang.annotation.")) {
674674
return this.objectSourceClass;
675675
}
676676
if (className.startsWith("java")) {
@@ -1017,7 +1017,7 @@ public Set<SourceClass> getAnnotations() {
10171017
Set<SourceClass> result = new LinkedHashSet<>();
10181018
if (this.source instanceof Class) {
10191019
Class<?> sourceClass = (Class<?>) this.source;
1020-
for (Annotation ann : sourceClass.getAnnotations()) {
1020+
for (Annotation ann : sourceClass.getDeclaredAnnotations()) {
10211021
Class<?> annType = ann.annotationType();
10221022
if (!annType.getName().startsWith("java")) {
10231023
try {

spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public StandardAnnotationMetadata(Class<?> introspectedClass) {
6868
*/
6969
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
7070
super(introspectedClass);
71-
this.annotations = introspectedClass.getAnnotations();
71+
this.annotations = introspectedClass.getDeclaredAnnotations();
7272
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
7373
}
7474

spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.annotation.Annotation;
2121
import java.lang.annotation.Documented;
2222
import java.lang.annotation.ElementType;
23+
import java.lang.annotation.Inherited;
2324
import java.lang.annotation.Retention;
2425
import java.lang.annotation.RetentionPolicy;
2526
import java.lang.annotation.Target;
@@ -52,7 +53,7 @@
5253
public class AnnotationMetadataTests {
5354

5455
@Test
55-
public void standardAnnotationMetadata() throws Exception {
56+
public void standardAnnotationMetadata() {
5657
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class, true);
5758
doTestAnnotationInfo(metadata);
5859
doTestMethodAnnotationInfo(metadata);
@@ -68,7 +69,7 @@ public void asmAnnotationMetadata() throws Exception {
6869
}
6970

7071
@Test
71-
public void standardAnnotationMetadataForSubclass() throws Exception {
72+
public void standardAnnotationMetadataForSubclass() {
7273
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponentSubClass.class, true);
7374
doTestSubClassAnnotationInfo(metadata);
7475
}
@@ -104,7 +105,7 @@ private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
104105
}
105106

106107
@Test
107-
public void standardAnnotationMetadataForInterface() throws Exception {
108+
public void standardAnnotationMetadataForInterface() {
108109
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotationMetadata.class, true);
109110
doTestMetadataForInterfaceClass(metadata);
110111
}
@@ -132,7 +133,7 @@ private void doTestMetadataForInterfaceClass(AnnotationMetadata metadata) {
132133
}
133134

134135
@Test
135-
public void standardAnnotationMetadataForAnnotation() throws Exception {
136+
public void standardAnnotationMetadataForAnnotation() {
136137
AnnotationMetadata metadata = new StandardAnnotationMetadata(Component.class, true);
137138
doTestMetadataForAnnotationClass(metadata);
138139
}
@@ -172,7 +173,7 @@ private void doTestMetadataForAnnotationClass(AnnotationMetadata metadata) {
172173
* 'true' as is done in the main test above.
173174
*/
174175
@Test
175-
public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() throws Exception {
176+
public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() {
176177
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class);
177178
AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName());
178179
Annotation[] nestedAnnoArray = (Annotation[]) specialAttrs.get("nestedAnnoArray");
@@ -233,6 +234,20 @@ public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsin
233234
assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
234235
}
235236

237+
@Test
238+
public void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
239+
AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationExtended.class);
240+
assertFalse(metadata.hasAnnotation(NamedComposedAnnotation.class.getName()));
241+
}
242+
243+
@Test
244+
public void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
245+
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
246+
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedComposedAnnotationExtended.class.getName());
247+
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
248+
assertFalse(metadata.hasAnnotation(NamedComposedAnnotation.class.getName()));
249+
}
250+
236251

237252
private void assertMultipleAnnotationsWithIdenticalAttributeNames(AnnotationMetadata metadata) {
238253
AnnotationAttributes attributes1 = (AnnotationAttributes) metadata.getAnnotationAttributes(
@@ -545,11 +560,15 @@ public static class NamedAnnotationsClass {
545560
@NamedAnnotation3(name = "name 3")
546561
@Retention(RetentionPolicy.RUNTIME)
547562
@Target(ElementType.TYPE)
563+
@Inherited
548564
public @interface NamedComposedAnnotation {
549565
}
550566

551567
@NamedComposedAnnotation
552568
public static class NamedComposedAnnotationClass {
553569
}
554570

571+
public static class NamedComposedAnnotationExtended extends NamedComposedAnnotationClass {
572+
}
573+
555574
}

0 commit comments

Comments
 (0)