28
28
import java .util .Set ;
29
29
30
30
import org .junit .Test ;
31
+
31
32
import org .springframework .core .annotation .AnnotationAttributes ;
32
33
import org .springframework .core .type .classreading .MetadataReader ;
33
34
import org .springframework .core .type .classreading .MetadataReaderFactory ;
34
35
import org .springframework .core .type .classreading .SimpleMetadataReaderFactory ;
35
36
import org .springframework .stereotype .Component ;
36
- import org .springframework .util .MultiValueMap ;
37
37
38
38
import static org .hamcrest .CoreMatchers .*;
39
39
import static org .junit .Assert .*;
@@ -112,23 +112,7 @@ public void metaAnnotationOverridesUsingAnnotationMetadataReadingVisitor() throw
112
112
assertMetaAnnotationOverrides (metadata );
113
113
}
114
114
115
- /**
116
- * @param metadata the metadata for {@link ComposedConfigurationWithAttributeOverridesClass}
117
- */
118
115
private void assertMetaAnnotationOverrides (AnnotationMetadata metadata ) {
119
- assertAllAttributesForMetaAnnotationOverrides (metadata );
120
- assertAttributesForMetaAnnotationOverrides (metadata );
121
-
122
- // SPR-11710: Invoke a 2nd time after invoking getAnnotationAttributes() in order
123
- // to ensure that getMergedAnnotationAttributes() in AnnotationReadingVisitorUtils
124
- // does not mutate the state of the metadata.
125
- assertAllAttributesForMetaAnnotationOverrides (metadata );
126
- }
127
-
128
- /**
129
- * @param metadata the metadata for {@link ComposedConfigurationWithAttributeOverridesClass}
130
- */
131
- private void assertAttributesForMetaAnnotationOverrides (AnnotationMetadata metadata ) {
132
116
AnnotationAttributes attributes = (AnnotationAttributes ) metadata .getAnnotationAttributes (
133
117
TestComponentScan .class .getName (), false );
134
118
String [] basePackages = attributes .getStringArray ("basePackages" );
@@ -141,27 +125,60 @@ private void assertAttributesForMetaAnnotationOverrides(AnnotationMetadata metad
141
125
}
142
126
143
127
/**
144
- * @param metadata the metadata for {@link ComposedConfigurationWithAttributeOverridesClass}
128
+ * https://jira.spring.io/browse/SPR-11649
145
129
*/
146
- private void assertAllAttributesForMetaAnnotationOverrides (AnnotationMetadata metadata ) {
147
- MultiValueMap <String , Object > map = metadata .getAllAnnotationAttributes (TestComponentScan .class .getName ());
148
- List <Object > basePackages = map .get ("basePackages" );
149
- assertThat ("length of basePackages list" , basePackages .size (), is (1 ));
130
+ @ Test
131
+ public void multipleAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata () {
132
+ AnnotationMetadata metadata = new StandardAnnotationMetadata (NamedAnnotationsClass .class );
133
+ assertMultipleAnnotationsWithIdenticalAttributeNames (metadata );
134
+ }
150
135
151
- // Ideally, the expected base package should be "org.example.componentscan", but
152
- // since Spring's annotation processing currently does not support meta-annotation
153
- // attribute overrides when searching for "all attributes", the actual value found
154
- // is "bogus".
155
- String expectedBasePackage = "bogus" ;
156
- assertThat ("basePackages[0]" , ((String []) basePackages .get (0 ))[0 ], is (expectedBasePackage ));
136
+ /**
137
+ * https://jira.spring.io/browse/SPR-11649
138
+ */
139
+ @ Test
140
+ public void multipleAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor () throws Exception {
141
+ MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory ();
142
+ MetadataReader metadataReader = metadataReaderFactory .getMetadataReader (NamedAnnotationsClass .class .getName ());
143
+ AnnotationMetadata metadata = metadataReader .getAnnotationMetadata ();
144
+ assertMultipleAnnotationsWithIdenticalAttributeNames (metadata );
145
+ }
157
146
158
- List <Object > value = map .get ("value" );
159
- assertThat ("length of value list" , value .size (), is (1 ));
160
- assertThat ("length of 0th value array" , ((String []) value .get (0 )).length , is (0 ));
147
+ /**
148
+ * https://jira.spring.io/browse/SPR-11649
149
+ */
150
+ @ Test
151
+ public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata () {
152
+ AnnotationMetadata metadata = new StandardAnnotationMetadata (NamedComposedAnnotationClass .class );
153
+ assertMultipleAnnotationsWithIdenticalAttributeNames (metadata );
154
+ }
161
155
162
- List <Object > basePackageClasses = map .get ("basePackageClasses" );
163
- assertThat ("length of basePackageClasses list" , basePackageClasses .size (), is (1 ));
164
- assertThat ("length of 0th basePackageClasses array" , ((Class <?>[]) basePackageClasses .get (0 )).length , is (0 ));
156
+ /**
157
+ * https://jira.spring.io/browse/SPR-11649
158
+ */
159
+ @ Test
160
+ public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor () throws Exception {
161
+ MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory ();
162
+ MetadataReader metadataReader = metadataReaderFactory .getMetadataReader (NamedComposedAnnotationClass .class .getName ());
163
+ AnnotationMetadata metadata = metadataReader .getAnnotationMetadata ();
164
+ assertMultipleAnnotationsWithIdenticalAttributeNames (metadata );
165
+ }
166
+
167
+ private void assertMultipleAnnotationsWithIdenticalAttributeNames (AnnotationMetadata metadata ) {
168
+ AnnotationAttributes attributes1 = (AnnotationAttributes ) metadata .getAnnotationAttributes (
169
+ NamedAnnotation1 .class .getName (), false );
170
+ String name1 = attributes1 .getString ("name" );
171
+ assertThat ("name of NamedAnnotation1" , name1 , is ("name 1" ));
172
+
173
+ AnnotationAttributes attributes2 = (AnnotationAttributes ) metadata .getAnnotationAttributes (
174
+ NamedAnnotation2 .class .getName (), false );
175
+ String name2 = attributes2 .getString ("name" );
176
+ assertThat ("name of NamedAnnotation2" , name2 , is ("name 2" ));
177
+
178
+ AnnotationAttributes attributes3 = (AnnotationAttributes ) metadata .getAnnotationAttributes (
179
+ NamedAnnotation3 .class .getName (), false );
180
+ String name3 = attributes3 .getString ("name" );
181
+ assertThat ("name of NamedAnnotation3" , name3 , is ("name 3" ));
165
182
}
166
183
167
184
private void doTestAnnotationInfo (AnnotationMetadata metadata ) {
@@ -389,6 +406,7 @@ public void meta() {
389
406
}
390
407
}
391
408
409
+ @ SuppressWarnings ({ "serial" })
392
410
private static class AnnotatedComponentSubClass extends AnnotatedComponent {
393
411
394
412
}
@@ -425,4 +443,40 @@ private static class AnnotatedComponentSubClass extends AnnotatedComponent {
425
443
public static class ComposedConfigurationWithAttributeOverridesClass {
426
444
}
427
445
446
+ @ Retention (RetentionPolicy .RUNTIME )
447
+ @ Target (ElementType .TYPE )
448
+ public static @interface NamedAnnotation1 {
449
+ String name () default "" ;
450
+ }
451
+
452
+ @ Retention (RetentionPolicy .RUNTIME )
453
+ @ Target (ElementType .TYPE )
454
+ public static @interface NamedAnnotation2 {
455
+ String name () default "" ;
456
+ }
457
+
458
+ @ Retention (RetentionPolicy .RUNTIME )
459
+ @ Target (ElementType .TYPE )
460
+ public static @interface NamedAnnotation3 {
461
+ String name () default "" ;
462
+ }
463
+
464
+ @ NamedAnnotation1 (name = "name 1" )
465
+ @ NamedAnnotation2 (name = "name 2" )
466
+ @ NamedAnnotation3 (name = "name 3" )
467
+ public static class NamedAnnotationsClass {
468
+ }
469
+
470
+ @ NamedAnnotation1 (name = "name 1" )
471
+ @ NamedAnnotation2 (name = "name 2" )
472
+ @ NamedAnnotation3 (name = "name 3" )
473
+ @ Retention (RetentionPolicy .RUNTIME )
474
+ @ Target (ElementType .TYPE )
475
+ public static @interface NamedComposedAnnotation {
476
+ }
477
+
478
+ @ NamedComposedAnnotation
479
+ public static class NamedComposedAnnotationClass {
480
+ }
481
+
428
482
}
0 commit comments