Skip to content

Commit 83909e6

Browse files
committed
Consistent exposure of empty attribute arrays in AnnotationMetadata
Issue: SPR-17347
1 parent fdf3403 commit 83909e6

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.core.type.classreading;
1818

19+
import java.lang.annotation.Annotation;
1920
import java.lang.reflect.Array;
2021
import java.util.ArrayList;
2122
import java.util.List;
@@ -82,6 +83,20 @@ public void visitEnd() {
8283
if (!this.allNestedAttributes.isEmpty()) {
8384
this.attributes.put(this.attributeName, this.allNestedAttributes.toArray(new AnnotationAttributes[0]));
8485
}
86+
else if (!this.attributes.containsKey(this.attributeName)) {
87+
Class<? extends Annotation> annotationType = this.attributes.annotationType();
88+
if (annotationType != null) {
89+
try {
90+
Class<?> attributeType = annotationType.getMethod(this.attributeName).getReturnType();
91+
if (attributeType.isArray()) {
92+
this.attributes.put(this.attributeName, Array.newInstance(attributeType.getComponentType(), 0));
93+
}
94+
}
95+
catch (NoSuchMethodException ex) {
96+
// Corresponding attribute method not found: cannot expose empty array.
97+
}
98+
}
99+
}
85100
}
86101

87102
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,9 @@ private void doTestAnnotationInfo(AnnotationMetadata metadata) {
338338
allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
339339
assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
340340
allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("additional");
341-
assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
341+
assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "")))));
342+
assertEquals("", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("additional"));
343+
assertEquals(0, ((String[]) metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("additionalArray")).length);
342344
}
343345
{ // perform tests with classValuesAsString = true
344346
AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(
@@ -425,6 +427,8 @@ public static enum SomeEnum {
425427
String myValue() default "";
426428

427429
String additional() default "direct";
430+
431+
String[] additionalArray() default "direct";
428432
}
429433

430434
@Target(ElementType.TYPE)
@@ -470,7 +474,7 @@ public enum SubclassEnum {
470474
nestedAnno = @NestedAnno(value = "na", anEnum = SomeEnum.LABEL1, classArray = {String.class}),
471475
nestedAnnoArray = {@NestedAnno, @NestedAnno(value = "na1", anEnum = SomeEnum.LABEL2, classArray = {Number.class})})
472476
@SuppressWarnings({"serial", "unused"})
473-
@DirectAnnotation("direct")
477+
@DirectAnnotation(value = "direct", additional = "", additionalArray = {})
474478
@MetaMetaAnnotation
475479
@EnumSubclasses({SubclassEnum.FOO, SubclassEnum.BAR})
476480
private static class AnnotatedComponent implements Serializable {

0 commit comments

Comments
 (0)