diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java b/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java index 44007afb4fe9..3d7f7392a331 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java @@ -81,7 +81,8 @@ private AttributeMethods(@Nullable Class annotationType, M foundNestedAnnotation = true; } ReflectionUtils.makeAccessible(method); - this.canThrowTypeNotPresentException[i] = (type == Class.class || type == Class[].class || type.isEnum()); + this.canThrowTypeNotPresentException[i] = (type == Class.class || type == Class[].class || + type.isEnum() || (type.isArray() && type.componentType().isEnum())); } this.hasDefaultValueMethod = foundDefaultValueMethod; this.hasNestedAnnotation = foundNestedAnnotation; diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java index e9602d452376..8d5d55ee4299 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AttributeMethodsTests.java @@ -89,6 +89,18 @@ void canThrowTypeNotPresentExceptionWhenHasClassArrayAttributeReturnsTrue() { assertThat(methods.canThrowTypeNotPresentException(0)).isTrue(); } + @Test + void canThrowTypeNotPresentExceptionWhenHasEnumArrayAttributeReturnsTrue() { + AttributeMethods methods = AttributeMethods.forAnnotationType(EnumArrayValue.class); + assertThat(methods.canThrowTypeNotPresentException(0)).isTrue(); + } + + @Test + void canThrowTypeNotPresentExceptionWhenHasNonEnumArrayAttributeReturnsFalse() { + AttributeMethods methods = AttributeMethods.forAnnotationType(StringArrayValue.class); + assertThat(methods.canThrowTypeNotPresentException(0)).isFalse(); + } + @Test void canThrowTypeNotPresentExceptionWhenNotClassOrClassArrayAttributeReturnsFalse() { AttributeMethods methods = AttributeMethods.forAnnotationType(ValueOnly.class); @@ -141,6 +153,38 @@ void validateWhenDoesNotHaveTypeNotPresentExceptionThrowsNothing() { attributes.validate(annotation); } + @Test + void isValidWhenHasEnumConstantNotPresentExceptionReturnsFalse() { + EnumArrayValue annotation = mockAnnotation(EnumArrayValue.class); + given(annotation.value()).willThrow(new EnumConstantNotPresentException(ExampleEnum.class, "MISSING")); + AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType()); + assertThat(attributes.canLoad(annotation, getClass())).isFalse(); + } + + @Test + void isValidWhenDoesNotHaveEnumConstantNotPresentExceptionReturnsTrue() { + EnumArrayValue annotation = mockAnnotation(EnumArrayValue.class); + given(annotation.value()).willReturn(new ExampleEnum[] {ExampleEnum.ONE}); + AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType()); + assertThat(attributes.canLoad(annotation, getClass())).isTrue(); + } + + @Test + void validateWhenHasEnumConstantNotPresentExceptionThrowsException() { + EnumArrayValue annotation = mockAnnotation(EnumArrayValue.class); + given(annotation.value()).willThrow(new EnumConstantNotPresentException(ExampleEnum.class, "MISSING")); + AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType()); + assertThatIllegalStateException().isThrownBy(() -> attributes.validate(annotation)); + } + + @Test + void validateWhenDoesNotHaveEnumConstantNotPresentExceptionThrowsNothing() { + EnumArrayValue annotation = mockAnnotation(EnumArrayValue.class); + given(annotation.value()).willReturn(new ExampleEnum[] {ExampleEnum.ONE}); + AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType()); + attributes.validate(annotation); + } + private List getAll(AttributeMethods attributes) { List result = new ArrayList<>(attributes.size()); for (int i = 0; i < attributes.size(); i++) { @@ -208,4 +252,24 @@ private A mockAnnotation(Class annotationType) { } + @Retention(RetentionPolicy.RUNTIME) + @interface EnumArrayValue { + + ExampleEnum[] value(); + + } + + @Retention(RetentionPolicy.RUNTIME) + @interface StringArrayValue { + + String[] value(); + + } + + enum ExampleEnum { + + ONE + + } + }