Honor contract of @Repeatable in AnnotationUtils
This commit introduces a minor bug fix for getRepeatableAnnotations() so that it fully complies with the contract of Java's getAnnotationsByType() method with regard to repeatable annotations declared on multiple superclasses. Issue: SPR-13068
This commit is contained in:
parent
de9f27872e
commit
594c330205
|
@ -305,6 +305,13 @@ public abstract class AnnotationUtils {
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (annotatedElement instanceof Class) {
|
||||||
|
Class<?> superclass = ((Class<?>) annotatedElement).getSuperclass();
|
||||||
|
if ((superclass != null) && (Object.class != superclass)) {
|
||||||
|
return getRepeatableAnnotations(superclass, annotationType, containerAnnotationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return getRepeatableAnnotations(annotatedElement, annotationType, containerAnnotationType, false);
|
return getRepeatableAnnotations(annotatedElement, annotationType, containerAnnotationType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,6 +586,25 @@ public class AnnotationUtilsTests {
|
||||||
assertThat(values, is(expectedValuesSpring));
|
assertThat(values, is(expectedValuesSpring));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepeatableAnnotationsDeclaredOnMultipleSuperclasses() {
|
||||||
|
final Class<?> clazz = SubSubMyRepeatableWithAdditionalLocalDeclarationsClass.class;
|
||||||
|
final List<String> expectedValuesJava = Arrays.asList("X", "Y", "Z");
|
||||||
|
final List<String> expectedValuesSpring = Arrays.asList("X", "Y", "Z", "meta2");
|
||||||
|
|
||||||
|
// Java 8
|
||||||
|
MyRepeatable[] array = clazz.getAnnotationsByType(MyRepeatable.class);
|
||||||
|
assertNotNull(array);
|
||||||
|
List<String> values = stream(array).map(MyRepeatable::value).collect(toList());
|
||||||
|
assertThat(values, is(expectedValuesJava));
|
||||||
|
|
||||||
|
// Spring
|
||||||
|
Set<MyRepeatable> set = getRepeatableAnnotations(clazz, MyRepeatable.class, MyRepeatableContainer.class);
|
||||||
|
assertNotNull(set);
|
||||||
|
values = set.stream().map(MyRepeatable::value).collect(toList());
|
||||||
|
assertThat(values, is(expectedValuesSpring));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDeclaredRepeatableAnnotationsDeclaredOnClass() {
|
public void getDeclaredRepeatableAnnotationsDeclaredOnClass() {
|
||||||
final List<String> expectedValuesJava = Arrays.asList("A", "B", "C");
|
final List<String> expectedValuesJava = Arrays.asList("A", "B", "C");
|
||||||
|
@ -1358,6 +1377,10 @@ public class AnnotationUtilsTests {
|
||||||
static class SubMyRepeatableWithAdditionalLocalDeclarationsClass extends MyRepeatableClass {
|
static class SubMyRepeatableWithAdditionalLocalDeclarationsClass extends MyRepeatableClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class SubSubMyRepeatableWithAdditionalLocalDeclarationsClass extends
|
||||||
|
SubMyRepeatableWithAdditionalLocalDeclarationsClass {
|
||||||
|
}
|
||||||
|
|
||||||
enum RequestMethod {
|
enum RequestMethod {
|
||||||
GET, POST
|
GET, POST
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue