diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java index e2478a7eb947b20dc5425f0c4474449b01d6f32e..b439926e2d73edd75fb91d399a2fb0cd877c2eb7 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.function.BiFunction; @@ -179,30 +178,25 @@ final class AnnotationTypeMapping { } if (isAliasPair(target) && checkAliasPair) { AliasFor targetAliasFor = target.getAnnotation(AliasFor.class); - if (targetAliasFor == null) { - throw new AnnotationConfigurationException(String.format( - "%s must be declared as an @AliasFor '%s'.", - StringUtils.capitalize(AttributeMethods.describe(target)), - attribute.getName())); - } - Method mirror = resolveAliasTarget(target, targetAliasFor, false); - if (!mirror.equals(attribute)) { - throw new AnnotationConfigurationException(String.format( - "%s must be declared as an @AliasFor '%s', not '%s'.", - StringUtils.capitalize(AttributeMethods.describe(target)), - attribute.getName(), mirror.getName())); + if (targetAliasFor != null) { + Method mirror = resolveAliasTarget(target, targetAliasFor, false); + if (!mirror.equals(attribute)) { + throw new AnnotationConfigurationException(String.format( + "%s must be declared as an @AliasFor '%s', not '%s'.", + StringUtils.capitalize(AttributeMethods.describe(target)), + attribute.getName(), mirror.getName())); + } } } return target; } private boolean isAliasPair(Method target) { - return target.getDeclaringClass().equals(this.annotationType); + return (this.annotationType == target.getDeclaringClass()); } private boolean isCompatibleReturnType(Class attributeType, Class targetType) { - return Objects.equals(attributeType, targetType) || - Objects.equals(attributeType, targetType.getComponentType()); + return (attributeType == targetType || attributeType == targetType.getComponentType()); } private void processAliases() { diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java index 4c0c108bbe2dd32469824f1605882c751e3b0a99..650078d10591e1bd133c802d17d570f47e857caa 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java @@ -1200,7 +1200,7 @@ class AnnotatedElementUtilsTests { @AliasFor("basePackages") String[] value() default {}; - @AliasFor("value") + // Intentionally no alias declaration for "value" String[] basePackages() default {}; Filter[] excludeFilters() default {}; @@ -1485,7 +1485,7 @@ class AnnotatedElementUtilsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface ValueAttribute { + @interface ValueAttribute { String[] value(); @@ -1493,7 +1493,7 @@ class AnnotatedElementUtilsTests { @Retention(RetentionPolicy.RUNTIME) @ValueAttribute("FromValueAttributeMeta") - static @interface ValueAttributeMeta { + @interface ValueAttributeMeta { @AliasFor("alias") String[] value() default {}; @@ -1505,7 +1505,7 @@ class AnnotatedElementUtilsTests { @Retention(RetentionPolicy.RUNTIME) @ValueAttributeMeta("FromValueAttributeMetaMeta") - static @interface ValueAttributeMetaMeta { + @interface ValueAttributeMetaMeta { } @ValueAttributeMetaMeta diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java index 6e70e6c7f304301974e0b516e851fe381fff7675..fd3f12b7cc15c98deb90e0c58e964d1a33e70b88 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java @@ -158,15 +158,6 @@ class AnnotationTypeMappingsTests { + "] must declare the same return type."); } - @Test - void forAnnotationTypeWhenAliasForToSelfNonAnnotatedAttribute() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForToSelfNonAnnotatedAttribute.class)) - .withMessage("Attribute 'other' in annotation [" - + AliasForToSelfNonAnnotatedAttribute.class.getName() - + "] must be declared as an @AliasFor 'test'."); - } - @Test void forAnnotationTypeWhenAliasForToSelfAnnotatedToOtherAttribute() { assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> @@ -554,67 +545,67 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface SimpleAnnotation { + @interface SimpleAnnotation { } @Retention(RetentionPolicy.RUNTIME) @Inherited @UsesSunMisc - static @interface WithSpringLangAnnotation { + @interface WithSpringLangAnnotation { } @Retention(RetentionPolicy.RUNTIME) @A @B - static @interface MetaAnnotated { + @interface MetaAnnotated { } @Retention(RetentionPolicy.RUNTIME) @AA @AB - static @interface A { + @interface A { } @Retention(RetentionPolicy.RUNTIME) - static @interface AA { + @interface AA { } @Retention(RetentionPolicy.RUNTIME) @ABC - static @interface AB { + @interface AB { } @Retention(RetentionPolicy.RUNTIME) - static @interface ABC { + @interface ABC { } @Retention(RetentionPolicy.RUNTIME) - static @interface B { + @interface B { } @Retention(RetentionPolicy.RUNTIME) @Repeating @Repeating - static @interface WithRepeatedMetaAnnotations { + @interface WithRepeatedMetaAnnotations { } @Retention(RetentionPolicy.RUNTIME) @Repeatable(Repeatings.class) - static @interface Repeating { + @interface Repeating { } @Retention(RetentionPolicy.RUNTIME) - static @interface Repeatings { + @interface Repeatings { Repeating[] value(); @@ -622,24 +613,24 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @SelfAnnotated - static @interface SelfAnnotated { + @interface SelfAnnotated { } @Retention(RetentionPolicy.RUNTIME) @LoopB - static @interface LoopA { + @interface LoopA { } @Retention(RetentionPolicy.RUNTIME) @LoopA - static @interface LoopB { + @interface LoopB { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForWithBothValueAndAttribute { + @interface AliasForWithBothValueAndAttribute { @AliasFor(value = "bar", attribute = "foo") String test(); @@ -647,7 +638,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToSelfNonExistingAttribute { + @interface AliasForToSelfNonExistingAttribute { @AliasFor("missing") String test() default ""; @@ -658,7 +649,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @AliasForToOtherNonExistingAttributeTarget - static @interface AliasForToOtherNonExistingAttribute { + @interface AliasForToOtherNonExistingAttribute { @AliasFor(annotation = AliasForToOtherNonExistingAttributeTarget.class, attribute = "missing") String test() default ""; @@ -666,14 +657,14 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToOtherNonExistingAttributeTarget { + @interface AliasForToOtherNonExistingAttributeTarget { String other() default ""; } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToSelf { + @interface AliasForToSelf { @AliasFor("test") String test() default ""; @@ -682,7 +673,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @AliasForWithArrayCompatibleReturnTypesTarget - static @interface AliasForWithArrayCompatibleReturnTypes { + @interface AliasForWithArrayCompatibleReturnTypes { @AliasFor(annotation = AliasForWithArrayCompatibleReturnTypesTarget.class) String test() default ""; @@ -690,14 +681,14 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForWithArrayCompatibleReturnTypesTarget { + @interface AliasForWithArrayCompatibleReturnTypesTarget { String[] test() default {}; } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForWithIncompatibleReturnTypes { + @interface AliasForWithIncompatibleReturnTypes { @AliasFor(annotation = AliasForWithIncompatibleReturnTypesTarget.class) String[] test() default {}; @@ -705,24 +696,14 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForWithIncompatibleReturnTypesTarget { - - String test() default ""; - - } - - @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToSelfNonAnnotatedAttribute { + @interface AliasForWithIncompatibleReturnTypesTarget { - @AliasFor("other") String test() default ""; - String other() default ""; - } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToSelfAnnotatedToOtherAttribute { + @interface AliasForToSelfAnnotatedToOtherAttribute { @AliasFor("b") String a() default ""; @@ -736,7 +717,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForNonMetaAnnotated { + @interface AliasForNonMetaAnnotated { @AliasFor(annotation = AliasForNonMetaAnnotatedTarget.class) String test() default ""; @@ -744,14 +725,14 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForNonMetaAnnotatedTarget { + @interface AliasForNonMetaAnnotatedTarget { String test() default ""; } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForSelfWithDifferentDefaults { + @interface AliasForSelfWithDifferentDefaults { @AliasFor("b") String a() default "a"; @@ -762,7 +743,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForSelfWithMissingDefault { + @interface AliasForSelfWithMissingDefault { @AliasFor("b") String a() default "a"; @@ -774,7 +755,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @AliasWithExplicitMirrorAndDifferentDefaultsTarget - static @interface AliasWithExplicitMirrorAndDifferentDefaults { + @interface AliasWithExplicitMirrorAndDifferentDefaults { @AliasFor(annotation = AliasWithExplicitMirrorAndDifferentDefaultsTarget.class, attribute = "a") String a() default "x"; @@ -788,7 +769,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasWithExplicitMirrorAndDifferentDefaultsTarget { + @interface AliasWithExplicitMirrorAndDifferentDefaultsTarget { String a() default ""; @@ -796,7 +777,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @MappedTarget - static @interface Mapped { + @interface Mapped { String convention() default ""; @@ -806,7 +787,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface MappedTarget { + @interface MappedTarget { String convention() default ""; @@ -815,7 +796,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasPair { + @interface AliasPair { @AliasFor("b") String a() default ""; @@ -827,7 +808,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @ImplicitMirrorsTarget - static @interface ImplicitMirrors { + @interface ImplicitMirrors { @AliasFor(annotation = ImplicitMirrorsTarget.class, attribute = "c") String a() default ""; @@ -838,7 +819,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface ImplicitMirrorsTarget { + @interface ImplicitMirrorsTarget { @AliasFor("d") String c() default ""; @@ -850,7 +831,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @ThreeDeepB - static @interface ThreeDeepA { + @interface ThreeDeepA { @AliasFor(annotation = ThreeDeepB.class, attribute = "b1") String a1() default ""; @@ -871,7 +852,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @ThreeDeepC - static @interface ThreeDeepB { + @interface ThreeDeepB { @AliasFor(annotation = ThreeDeepC.class, attribute = "c1") String b1() default ""; @@ -882,7 +863,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface ThreeDeepC { + @interface ThreeDeepC { String c1() default ""; @@ -892,7 +873,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @DefinedAttributesTarget(a = "test") - static @interface DefinedAttributes { + @interface DefinedAttributes { @AliasFor(annotation = DefinedAttributesTarget.class, attribute = "b") String value(); @@ -900,7 +881,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface DefinedAttributesTarget { + @interface DefinedAttributesTarget { String a(); @@ -935,7 +916,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @MulipleRoutesToAliasB - static @interface MulipleRoutesToAliasA { + @interface MulipleRoutesToAliasA { @AliasFor(annotation = MulipleRoutesToAliasB.class, attribute = "b2") String a1() default ""; @@ -944,7 +925,7 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @MulipleRoutesToAliasC - static @interface MulipleRoutesToAliasB { + @interface MulipleRoutesToAliasB { @AliasFor(annotation = MulipleRoutesToAliasC.class, attribute = "c2") String b1() default ""; @@ -958,7 +939,7 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface MulipleRoutesToAliasC { + @interface MulipleRoutesToAliasC { @AliasFor("c2") String c1() default ""; @@ -970,14 +951,14 @@ class AnnotationTypeMappingsTests { @Retention(RetentionPolicy.RUNTIME) @ConventionToExplicitAliasesTarget - static @interface ConventionToExplicitAliases { + @interface ConventionToExplicitAliases { String test() default ""; } @Retention(RetentionPolicy.RUNTIME) - static @interface ConventionToExplicitAliasesTarget { + @interface ConventionToExplicitAliasesTarget { @AliasFor("test") String value() default ""; @@ -988,28 +969,28 @@ class AnnotationTypeMappingsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface ClassValue { + @interface ClassValue { Class value(); } @Retention(RetentionPolicy.RUNTIME) - static @interface ClassValueWithDefault { + @interface ClassValueWithDefault { Class value() default InputStream.class; } @Retention(RetentionPolicy.RUNTIME) - static @interface ClassArrayValueWithDefault { + @interface ClassArrayValueWithDefault { Class[] value() default { InputStream.class, OutputStream.class }; } @Retention(RetentionPolicy.RUNTIME) - static @interface NestedValue { + @interface NestedValue { ClassValue value() default @ClassValue(InputStream.class); diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java index 461b300a38b760daf3274fced43bf4aa08a89067..f0edf9c47400cf2febe9df0d7cd2da52cc426814 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java @@ -556,16 +556,6 @@ class AnnotationUtilsTests { assertThat(values).isEqualTo(asList("A", "B", "C", "meta1")); } - @Test - void getRepeatableAnnotationsDeclaredOnClassWithMissingAttributeAliasDeclaration() throws Exception { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - getRepeatableAnnotations(BrokenConfigHierarchyTestCase.class, BrokenContextConfig.class, BrokenHierarchy.class)) - .withMessageStartingWith("Attribute 'value' in") - .withMessageContaining(BrokenContextConfig.class.getName()) - .withMessageContaining("@AliasFor 'location'"); - - } - @Test void getRepeatableAnnotationsDeclaredOnClassWithAttributeAliases() { final List expectedLocations = asList("A", "B"); @@ -1415,17 +1405,6 @@ class AnnotationUtilsTests { Class klass() default Object.class; } - @Retention(RetentionPolicy.RUNTIME) - @interface BrokenContextConfig { - - // Intentionally missing: - // @AliasFor("location") - String value() default ""; - - @AliasFor("value") - String location() default ""; - } - /** * Mock of {@code org.springframework.test.context.ContextHierarchy}. */ @@ -1434,19 +1413,10 @@ class AnnotationUtilsTests { ContextConfig[] value(); } - @Retention(RetentionPolicy.RUNTIME) - @interface BrokenHierarchy { - BrokenContextConfig[] value(); - } - @Hierarchy({@ContextConfig("A"), @ContextConfig(location = "B")}) static class ConfigHierarchyTestCase { } - @BrokenHierarchy(@BrokenContextConfig) - static class BrokenConfigHierarchyTestCase { - } - @ContextConfig("simple.xml") static class SimpleConfigTestCase { } @@ -1825,13 +1795,13 @@ class AnnotationUtilsTests { @Retention(RetentionPolicy.RUNTIME) @Repeatable(TestRepeatableContainer.class) - static @interface TestRepeatable { + @interface TestRepeatable { String value(); } @Retention(RetentionPolicy.RUNTIME) - static @interface TestRepeatableContainer { + @interface TestRepeatableContainer { TestRepeatable[] value(); } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index 5b6e77ed8af789d569536e081f4426199f44cd5b..02fe39f0f33f9e715936d77110ced21b9161ff63 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -1308,18 +1308,6 @@ class MergedAnnotationsTests { assertThat(values).containsExactly("A", "B", "C", "meta1"); } - @Test - void getRepeatableDeclaredOnClassWithMissingAttributeAliasDeclaration() { - RepeatableContainers containers = RepeatableContainers.of( - BrokenContextConfiguration.class, BrokenHierarchy.class); - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - MergedAnnotations.from(BrokenHierarchyClass.class, SearchStrategy.TYPE_HIERARCHY, containers, - AnnotationFilter.PLAIN).get(BrokenHierarchy.class)) - .withMessageStartingWith("Attribute 'value' in") - .withMessageContaining(BrokenContextConfiguration.class.getName()) - .withMessageContaining("@AliasFor 'location'"); - } - @Test void getRepeatableDeclaredOnClassWithAttributeAliases() { assertThat(MergedAnnotations.from(HierarchyClass.class).stream( @@ -1329,8 +1317,7 @@ class MergedAnnotationsTests { MergedAnnotations annotations = MergedAnnotations.from(HierarchyClass.class, SearchStrategy.DIRECT, containers, AnnotationFilter.NONE); assertThat(annotations.stream(TestConfiguration.class).map( - annotation -> annotation.getString("location"))).containsExactly("A", - "B"); + annotation -> annotation.getString("location"))).containsExactly("A", "B"); assertThat(annotations.stream(TestConfiguration.class).map( annotation -> annotation.getString("value"))).containsExactly("A", "B"); } @@ -1488,17 +1475,6 @@ class MergedAnnotationsTests { .withMessageContaining("declares an alias for 'bar' which is not present"); } - @Test - void synthesizeWhenAttributeAliasWithoutMirroredAliasFor() throws Exception { - AliasForWithoutMirroredAliasFor annotation = AliasForWithoutMirroredAliasForClass.class.getAnnotation( - AliasForWithoutMirroredAliasFor.class); - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - MergedAnnotation.from(annotation)) - .withMessageStartingWith("Attribute 'bar' in") - .withMessageContaining(AliasForWithoutMirroredAliasFor.class.getName()) - .withMessageContaining("@AliasFor 'foo'"); - } - @Test void synthesizeWhenAttributeAliasWithMirroredAliasForWrongAttribute() throws Exception { @@ -3055,15 +3031,6 @@ class MergedAnnotationsTests { } } - @Retention(RetentionPolicy.RUNTIME) - @interface BrokenContextConfiguration { - - String value() default ""; - - @AliasFor("value") - String location() default ""; - } - @Retention(RetentionPolicy.RUNTIME) @interface TestConfiguration { @@ -3082,20 +3049,10 @@ class MergedAnnotationsTests { TestConfiguration[] value(); } - @Retention(RetentionPolicy.RUNTIME) - @interface BrokenHierarchy { - - BrokenContextConfiguration[] value(); - } - @Hierarchy({ @TestConfiguration("A"), @TestConfiguration(location = "B") }) static class HierarchyClass { } - @BrokenHierarchy(@BrokenContextConfiguration) - static class BrokenHierarchyClass { - } - @TestConfiguration("simple.xml") static class TestConfigurationClass { } @@ -3544,7 +3501,7 @@ class MergedAnnotationsTests { } @Retention(RetentionPolicy.RUNTIME) - static @interface ValueAttribute { + @interface ValueAttribute { String[] value(); @@ -3552,7 +3509,7 @@ class MergedAnnotationsTests { @Retention(RetentionPolicy.RUNTIME) @ValueAttribute("FromValueAttributeMeta") - static @interface ValueAttributeMeta { + @interface ValueAttributeMeta { String[] value() default {}; @@ -3560,7 +3517,7 @@ class MergedAnnotationsTests { @Retention(RetentionPolicy.RUNTIME) @ValueAttributeMeta("FromValueAttributeMetaMeta") - static @interface ValueAttributeMetaMeta { + @interface ValueAttributeMetaMeta { }