Don't detect annotations on superclass in StAnMeta

Changes introduced in conjunction with issue SPR-11475 altered the
behavior of StandardAnnotationMetadata such that annotations could be
detected on superclasses, specifically in the case where the
AnnotatedElementUtils.getAllAnnotationAttributes() method is invoked to
obtain multiple annotations of the same type (on the lowest level in the
class hierarchy), as is the case for @Profile and @Conditional.

This commit partially reverts these changes as follows:

 - All methods in AnnotatedElementUtils now set the
   traverseClassHierarchy to false, thereby effectively reverting the
   changes made in commit 1d30bf83a0.
   Note, however, that the changes made to AnnotationUtils remain in
   place.

 - Introduced tests in AnnotationMetadataTests that verify behavior
   present in Spring Framework 4.0.2 and earlier.

 - Updated tests in AnnotatedElementUtilsTests so that they pass against
   the reverted changes (i.e., align with the behavior present in Spring
   Framework 4.0.2 and earlier).

 - Refined Javadoc in AnnotationMetadata with regard to annotations
   being "present" vs. "defined".

 - Refined Javadoc in AnnotatedTypeMetadata.

Issue: SPR-11475, SPR-11595
This commit is contained in:
Sam Brannen
2014-03-25 17:48:06 +01:00
parent d970015d4d
commit a2f1169e82
5 changed files with 86 additions and 31 deletions

View File

@@ -103,7 +103,10 @@ public class AnnotatedElementUtilsTests {
AnnotationAttributes attributes = getAnnotationAttributes(SubSubClassWithInheritedAnnotation.class,
Transactional.class.getName());
assertNotNull("AnnotationAttributes for @Transactional on SubSubClassWithInheritedAnnotation", attributes);
assertEquals("readOnly flag for SubSubClassWithInheritedAnnotation.", true, attributes.getBoolean("readOnly"));
// TODO [SPR-11475] Set expected to true.
boolean expected = false;
assertEquals("readOnly flag for SubSubClassWithInheritedAnnotation.", expected, attributes.getBoolean("readOnly"));
}
@Test
@@ -112,7 +115,10 @@ public class AnnotatedElementUtilsTests {
Transactional.class.getName());
assertNotNull("AnnotationAttributtes for @Transactional on SubSubClassWithInheritedComposedAnnotation.",
attributes);
assertEquals("readOnly flag for SubSubClassWithInheritedComposedAnnotation.", true,
// TODO [SPR-11475] Set expected to true.
boolean expected = false;
assertEquals("readOnly flag for SubSubClassWithInheritedComposedAnnotation.", expected,
attributes.getBoolean("readOnly"));
}

View File

@@ -64,6 +64,20 @@ public class AnnotationMetadataTests {
doTestMethodAnnotationInfo(metadata);
}
@Test
public void standardAnnotationMetadataForSubclass() throws Exception {
AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponentSubClass.class, true);
doTestSubClassAnnotationInfo(metadata);
}
@Test
public void asmAnnotationMetadataForSubclass() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestSubClassAnnotationInfo(metadata);
}
/**
* In order to preserve backward-compatibility, {@link StandardAnnotationMetadata}
* defaults to return nested annotations and annotation arrays as actual
@@ -211,6 +225,21 @@ public class AnnotationMetadataTests {
}
}
private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
assertThat(metadata.getClassName(), is(AnnotatedComponentSubClass.class.getName()));
assertThat(metadata.isAnnotated(Component.class.getName()), is(false));
assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Component.class.getName()), is(false));
assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
assertThat(metadata.getAnnotationTypes().size(), is(0));
assertThat(metadata.getAnnotationAttributes(Component.class.getName()), nullValue());
assertThat(metadata.getAnnotatedMethods(DirectAnnotation.class.getName()).size(), equalTo(0));
assertThat(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()), equalTo(false));
assertThat(metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()), nullValue());
}
private void doTestMethodAnnotationInfo(AnnotationMetadata classMetadata) {
Set<MethodMetadata> methods = classMetadata.getAnnotatedMethods(TestAutowired.class.getName());
assertThat(methods.size(), is(1));
@@ -317,6 +346,10 @@ public class AnnotationMetadataTests {
}
}
private static class AnnotatedComponentSubClass extends AnnotatedComponent {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component