Support @Inherited again in reflection-based AnnotationMetadata
Spring Framework 5.2 introduced a regression in reflection-based AnnotationMetadata. Specifically, as of 5.2, StandardAnnotationMetadata no longer found @Inherited annotations from superclasses. This commit fixes this regression by switching to the INHERITED_ANNOTATIONS SearchStrategy when creating the MergedAnnotations used within StandardAnnotationMetadata, Note, however, that the discrepancy between StandardAnnotationMetadata and SimpleAnnotationMetadata (i.e., reflection-based vs. ASM-based) regarding @Inherited support still remains as it was prior to Spring Framework 5.2. Closes gh-24077
This commit is contained in:
parent
85016aef30
commit
7cedffc707
|
@ -85,7 +85,7 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
|
||||||
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
|
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
|
||||||
super(introspectedClass);
|
super(introspectedClass);
|
||||||
this.mergedAnnotations = MergedAnnotations.from(introspectedClass,
|
this.mergedAnnotations = MergedAnnotations.from(introspectedClass,
|
||||||
SearchStrategy.DIRECT, RepeatableContainers.none(),
|
SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none(),
|
||||||
AnnotationFilter.NONE);
|
AnnotationFilter.NONE);
|
||||||
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
|
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests demonstrating that the reflection-based {@link StandardAnnotationMetadata}
|
* Unit tests demonstrating that the reflection-based {@link StandardAnnotationMetadata}
|
||||||
* and ASM-based {@code AnnotationMetadataReadingVisitor} produce identical output.
|
* and ASM-based {@code SimpleAnnotationMetadata} produce <em>almost</em> identical output.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
@ -51,9 +51,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
class AnnotationMetadataTests {
|
class AnnotationMetadataTests {
|
||||||
|
|
||||||
private static final boolean reproduceGh24077 = false;
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void standardAnnotationMetadata() {
|
void standardAnnotationMetadata() {
|
||||||
AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponent.class);
|
AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponent.class);
|
||||||
|
@ -73,7 +70,7 @@ class AnnotationMetadataTests {
|
||||||
@Test
|
@Test
|
||||||
void standardAnnotationMetadataForSubclass() {
|
void standardAnnotationMetadataForSubclass() {
|
||||||
AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponentSubClass.class);
|
AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponentSubClass.class);
|
||||||
doTestSubClassAnnotationInfo(metadata);
|
doTestSubClassAnnotationInfo(metadata, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -81,10 +78,10 @@ class AnnotationMetadataTests {
|
||||||
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
|
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
|
||||||
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
|
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
|
||||||
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
|
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
|
||||||
doTestSubClassAnnotationInfo(metadata);
|
doTestSubClassAnnotationInfo(metadata, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
|
private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata, boolean asm) {
|
||||||
assertThat(metadata.getClassName()).isEqualTo(AnnotatedComponentSubClass.class.getName());
|
assertThat(metadata.getClassName()).isEqualTo(AnnotatedComponentSubClass.class.getName());
|
||||||
assertThat(metadata.isInterface()).isFalse();
|
assertThat(metadata.isInterface()).isFalse();
|
||||||
assertThat(metadata.isAnnotation()).isFalse();
|
assertThat(metadata.isAnnotation()).isFalse();
|
||||||
|
@ -97,16 +94,16 @@ class AnnotationMetadataTests {
|
||||||
assertThat(metadata.isAnnotated(Scope.class.getName())).isFalse();
|
assertThat(metadata.isAnnotated(Scope.class.getName())).isFalse();
|
||||||
assertThat(metadata.isAnnotated(SpecialAttr.class.getName())).isFalse();
|
assertThat(metadata.isAnnotated(SpecialAttr.class.getName())).isFalse();
|
||||||
|
|
||||||
if (reproduceGh24077) {
|
if (asm) {
|
||||||
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isTrue();
|
|
||||||
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isTrue();
|
|
||||||
assertThat(metadata.getAnnotationTypes()).containsExactly(NamedComposedAnnotation.class.getName());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isFalse();
|
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isFalse();
|
||||||
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isFalse();
|
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isFalse();
|
||||||
assertThat(metadata.getAnnotationTypes()).isEmpty();
|
assertThat(metadata.getAnnotationTypes()).isEmpty();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isTrue();
|
||||||
|
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isTrue();
|
||||||
|
assertThat(metadata.getAnnotationTypes()).containsExactly(NamedComposedAnnotation.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
assertThat(metadata.hasAnnotation(Component.class.getName())).isFalse();
|
assertThat(metadata.hasAnnotation(Component.class.getName())).isFalse();
|
||||||
assertThat(metadata.hasAnnotation(Scope.class.getName())).isFalse();
|
assertThat(metadata.hasAnnotation(Scope.class.getName())).isFalse();
|
||||||
|
@ -252,7 +249,7 @@ class AnnotationMetadataTests {
|
||||||
@Test
|
@Test
|
||||||
void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
|
void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
|
||||||
AnnotationMetadata metadata = AnnotationMetadata.introspect(NamedComposedAnnotationExtended.class);
|
AnnotationMetadata metadata = AnnotationMetadata.introspect(NamedComposedAnnotationExtended.class);
|
||||||
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isFalse();
|
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -294,29 +291,18 @@ class AnnotationMetadataTests {
|
||||||
|
|
||||||
assertThat(metadata.isAnnotated(Component.class.getName())).isTrue();
|
assertThat(metadata.isAnnotated(Component.class.getName())).isTrue();
|
||||||
|
|
||||||
if (reproduceGh24077) {
|
|
||||||
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isTrue();
|
assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isTrue();
|
||||||
}
|
|
||||||
|
|
||||||
assertThat(metadata.hasAnnotation(Component.class.getName())).isTrue();
|
assertThat(metadata.hasAnnotation(Component.class.getName())).isTrue();
|
||||||
assertThat(metadata.hasAnnotation(Scope.class.getName())).isTrue();
|
assertThat(metadata.hasAnnotation(Scope.class.getName())).isTrue();
|
||||||
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName())).isTrue();
|
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName())).isTrue();
|
||||||
|
|
||||||
if (reproduceGh24077) {
|
|
||||||
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isTrue();
|
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isTrue();
|
||||||
assertThat(metadata.getAnnotationTypes()).containsExactlyInAnyOrder(
|
assertThat(metadata.getAnnotationTypes()).containsExactlyInAnyOrder(
|
||||||
Component.class.getName(), Scope.class.getName(),
|
Component.class.getName(), Scope.class.getName(),
|
||||||
SpecialAttr.class.getName(), DirectAnnotation.class.getName(),
|
SpecialAttr.class.getName(), DirectAnnotation.class.getName(),
|
||||||
MetaMetaAnnotation.class.getName(), EnumSubclasses.class.getName(),
|
MetaMetaAnnotation.class.getName(), EnumSubclasses.class.getName(),
|
||||||
NamedComposedAnnotation.class.getName());
|
NamedComposedAnnotation.class.getName());
|
||||||
}
|
|
||||||
else {
|
|
||||||
assertThat(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())).isFalse();
|
|
||||||
assertThat(metadata.getAnnotationTypes()).containsExactlyInAnyOrder(
|
|
||||||
Component.class.getName(), Scope.class.getName(),
|
|
||||||
SpecialAttr.class.getName(), DirectAnnotation.class.getName(),
|
|
||||||
MetaMetaAnnotation.class.getName(), EnumSubclasses.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationAttributes compAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(Component.class.getName());
|
AnnotationAttributes compAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(Component.class.getName());
|
||||||
assertThat(compAttrs).hasSize(1);
|
assertThat(compAttrs).hasSize(1);
|
||||||
|
@ -513,6 +499,7 @@ class AnnotationMetadataTests {
|
||||||
@DirectAnnotation(value = "direct", additional = "", additionalArray = {})
|
@DirectAnnotation(value = "direct", additional = "", additionalArray = {})
|
||||||
@MetaMetaAnnotation
|
@MetaMetaAnnotation
|
||||||
@EnumSubclasses({SubclassEnum.FOO, SubclassEnum.BAR})
|
@EnumSubclasses({SubclassEnum.FOO, SubclassEnum.BAR})
|
||||||
|
@NamedComposedAnnotation
|
||||||
private static class AnnotatedComponent implements Serializable {
|
private static class AnnotatedComponent implements Serializable {
|
||||||
|
|
||||||
@TestAutowired
|
@TestAutowired
|
||||||
|
|
Loading…
Reference in New Issue