diff --git a/spring-context/src/main/java/org/springframework/context/annotation/DeferredImportSelector.java b/spring-context/src/main/java/org/springframework/context/annotation/DeferredImportSelector.java index 1dd9e5b511fc..6bca9156781c 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/DeferredImportSelector.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/DeferredImportSelector.java @@ -16,8 +16,6 @@ package org.springframework.context.annotation; -import java.util.Objects; - import org.springframework.core.type.AnnotationMetadata; import org.springframework.lang.Nullable; @@ -108,13 +106,17 @@ public boolean equals(@Nullable Object other) { return false; } Entry entry = (Entry) other; - return (Objects.equals(this.metadata, entry.metadata) && - Objects.equals(this.importClassName, entry.importClassName)); + return (this.metadata.equals(entry.metadata) && this.importClassName.equals(entry.importClassName)); } @Override public int hashCode() { - return Objects.hash(this.metadata, this.importClassName); + return (this.metadata.hashCode() * 31 + this.importClassName.hashCode()); + } + + @Override + public String toString() { + return this.importClassName; } } } 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 e2478a7eb947..b439926e2d73 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.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 @@ private Method resolveAliasTarget(Method attribute, AliasFor aliasFor, boolean c } 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/main/java/org/springframework/core/annotation/AttributeMethods.java b/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java index 13f0d64e035a..f5c06ff051e2 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 @@ -25,6 +25,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; +import org.springframework.util.ReflectionUtils; /** * Provides a quick way to access the attribute methods of an {@link Annotation} @@ -73,15 +74,11 @@ private AttributeMethods(@Nullable Class annotationType, M if (method.getDefaultValue() != null) { foundDefaultValueMethod = true; } - if (type.isAnnotation() || - (type.isArray() && type.getComponentType().isAnnotation())) { + if (type.isAnnotation() || (type.isArray() && type.getComponentType().isAnnotation())) { foundNestedAnnotation = true; } - method.setAccessible(true); - this.canThrowTypeNotPresentException[i] = - type == Class.class || - type == Class[].class || - type.isEnum(); + ReflectionUtils.makeAccessible(method); + this.canThrowTypeNotPresentException[i] = (type == Class.class || type == Class[].class || type.isEnum()); } this.hasDefaultValueMethod = foundDefaultValueMethod; this.hasNestedAnnotation = foundNestedAnnotation; diff --git a/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java b/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java index 01cb98c3facc..a235a581b072 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java @@ -20,7 +20,6 @@ import java.lang.annotation.Repeatable; import java.lang.reflect.Method; import java.util.Map; -import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -83,7 +82,7 @@ public boolean equals(@Nullable Object other) { if (other == null || getClass() != other.getClass()) { return false; } - return Objects.equals(this.parent, ((RepeatableContainers) other).parent); + return ObjectUtils.nullSafeEquals(this.parent, ((RepeatableContainers) other).parent); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java index 89eab8386f9c..fe1131bf16c4 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java @@ -23,7 +23,6 @@ import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.NoSuchElementException; -import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -90,7 +89,7 @@ public Object invoke(Object proxy, Method method, Object[] args) { } private boolean isAnnotationTypeMethod(Method method) { - return (Objects.equals(method.getName(), "annotationType") && method.getParameterCount() == 0); + return (method.getName().equals("annotationType") && method.getParameterCount() == 0); } /** diff --git a/spring-core/src/main/java/org/springframework/util/unit/DataUnit.java b/spring-core/src/main/java/org/springframework/util/unit/DataUnit.java index 3ade6a289b08..8b5dc4354d85 100644 --- a/spring-core/src/main/java/org/springframework/util/unit/DataUnit.java +++ b/spring-core/src/main/java/org/springframework/util/unit/DataUnit.java @@ -16,8 +16,6 @@ package org.springframework.util.unit; -import java.util.Objects; - /** * A standard set of {@link DataSize} units. * @@ -92,7 +90,7 @@ DataSize size() { */ public static DataUnit fromSuffix(String suffix) { for (DataUnit candidate : values()) { - if (Objects.equals(candidate.suffix, suffix)) { + if (candidate.suffix.equals(suffix)) { return candidate; } } 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 4c0c108bbe2d..650078d10591 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 @@ static class MetaCycleAnnotatedClass { @AliasFor("basePackages") String[] value() default {}; - @AliasFor("value") + // Intentionally no alias declaration for "value" String[] basePackages() default {}; Filter[] excludeFilters() default {}; @@ -1485,7 +1485,7 @@ class ForAnnotationsClass { } @Retention(RetentionPolicy.RUNTIME) - static @interface ValueAttribute { + @interface ValueAttribute { String[] value(); @@ -1493,7 +1493,7 @@ class ForAnnotationsClass { @Retention(RetentionPolicy.RUNTIME) @ValueAttribute("FromValueAttributeMeta") - static @interface ValueAttributeMeta { + @interface ValueAttributeMeta { @AliasFor("alias") String[] value() default {}; @@ -1505,7 +1505,7 @@ class ForAnnotationsClass { @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 6e70e6c7f304..fd3f12b7cc15 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 @@ void forAnnotationTypeWhenAliasForWithIncompatibleReturnTypes() { + "] 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 @@ private Object extractFromMap(Method attribute, Object map) { } @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 @@ private Object extractFromMap(Method attribute, Object map) { @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 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForToSelfNonExistingAttribute { + @interface AliasForToSelfNonExistingAttribute { @AliasFor("missing") String test() default ""; @@ -658,7 +649,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @AliasForToOtherNonExistingAttributeTarget - static @interface AliasForToOtherNonExistingAttribute { + @interface AliasForToOtherNonExistingAttribute { @AliasFor(annotation = AliasForToOtherNonExistingAttributeTarget.class, attribute = "missing") String test() default ""; @@ -666,14 +657,14 @@ private Object extractFromMap(Method attribute, Object map) { } @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 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @AliasForWithArrayCompatibleReturnTypesTarget - static @interface AliasForWithArrayCompatibleReturnTypes { + @interface AliasForWithArrayCompatibleReturnTypes { @AliasFor(annotation = AliasForWithArrayCompatibleReturnTypesTarget.class) String test() default ""; @@ -690,14 +681,14 @@ private Object extractFromMap(Method attribute, Object map) { } @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 @@ private Object extractFromMap(Method attribute, Object map) { } @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 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForNonMetaAnnotated { + @interface AliasForNonMetaAnnotated { @AliasFor(annotation = AliasForNonMetaAnnotatedTarget.class) String test() default ""; @@ -744,14 +725,14 @@ private Object extractFromMap(Method attribute, Object map) { } @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 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasForSelfWithMissingDefault { + @interface AliasForSelfWithMissingDefault { @AliasFor("b") String a() default "a"; @@ -774,7 +755,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @AliasWithExplicitMirrorAndDifferentDefaultsTarget - static @interface AliasWithExplicitMirrorAndDifferentDefaults { + @interface AliasWithExplicitMirrorAndDifferentDefaults { @AliasFor(annotation = AliasWithExplicitMirrorAndDifferentDefaultsTarget.class, attribute = "a") String a() default "x"; @@ -788,7 +769,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasWithExplicitMirrorAndDifferentDefaultsTarget { + @interface AliasWithExplicitMirrorAndDifferentDefaultsTarget { String a() default ""; @@ -796,7 +777,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @MappedTarget - static @interface Mapped { + @interface Mapped { String convention() default ""; @@ -806,7 +787,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface MappedTarget { + @interface MappedTarget { String convention() default ""; @@ -815,7 +796,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface AliasPair { + @interface AliasPair { @AliasFor("b") String a() default ""; @@ -827,7 +808,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @ImplicitMirrorsTarget - static @interface ImplicitMirrors { + @interface ImplicitMirrors { @AliasFor(annotation = ImplicitMirrorsTarget.class, attribute = "c") String a() default ""; @@ -838,7 +819,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface ImplicitMirrorsTarget { + @interface ImplicitMirrorsTarget { @AliasFor("d") String c() default ""; @@ -850,7 +831,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @ThreeDeepB - static @interface ThreeDeepA { + @interface ThreeDeepA { @AliasFor(annotation = ThreeDeepB.class, attribute = "b1") String a1() default ""; @@ -871,7 +852,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @ThreeDeepC - static @interface ThreeDeepB { + @interface ThreeDeepB { @AliasFor(annotation = ThreeDeepC.class, attribute = "c1") String b1() default ""; @@ -882,7 +863,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface ThreeDeepC { + @interface ThreeDeepC { String c1() default ""; @@ -892,7 +873,7 @@ private Object extractFromMap(Method attribute, Object map) { @Retention(RetentionPolicy.RUNTIME) @DefinedAttributesTarget(a = "test") - static @interface DefinedAttributes { + @interface DefinedAttributes { @AliasFor(annotation = DefinedAttributesTarget.class, attribute = "b") String value(); @@ -900,7 +881,7 @@ private Object extractFromMap(Method attribute, Object map) { } @Retention(RetentionPolicy.RUNTIME) - static @interface DefinedAttributesTarget { + @interface DefinedAttributesTarget { String a(); @@ -935,7 +916,7 @@ static class WithDefaultValueAliasPair { @Retention(RetentionPolicy.RUNTIME) @MulipleRoutesToAliasB - static @interface MulipleRoutesToAliasA { + @interface MulipleRoutesToAliasA { @AliasFor(annotation = MulipleRoutesToAliasB.class, attribute = "b2") String a1() default ""; @@ -944,7 +925,7 @@ static class WithDefaultValueAliasPair { @Retention(RetentionPolicy.RUNTIME) @MulipleRoutesToAliasC - static @interface MulipleRoutesToAliasB { + @interface MulipleRoutesToAliasB { @AliasFor(annotation = MulipleRoutesToAliasC.class, attribute = "c2") String b1() default ""; @@ -958,7 +939,7 @@ static class WithDefaultValueAliasPair { } @Retention(RetentionPolicy.RUNTIME) - static @interface MulipleRoutesToAliasC { + @interface MulipleRoutesToAliasC { @AliasFor("c2") String c1() default ""; @@ -970,14 +951,14 @@ static class WithDefaultValueAliasPair { @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 @@ static class WithDefaultValueAliasPair { } @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 461b300a38b7..f0edf9c47400 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 @@ void getRepeatableAnnotationsDeclaredOnMethod() throws Exception { 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 @@ public void handleMappedWithDifferentPathAndValueAttributes() { 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 @@ public void handleMappedWithDifferentPathAndValueAttributes() { 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 @@ interface ContextConfigMismatch { @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 5b6e77ed8af7..02fe39f0f33f 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 @@ void getRepeatableDeclaredOnMethod() throws Exception { 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 @@ void getRepeatableDeclaredOnClassWithAttributeAliases() { 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 @@ void synthesizeWhenAttributeAliasForNonexistentAttribute() throws Exception { .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 @@ public void handleMappedWithDifferentPathAndValueAttributes() { } } - @Retention(RetentionPolicy.RUNTIME) - @interface BrokenContextConfiguration { - - String value() default ""; - - @AliasFor("value") - String location() default ""; - } - @Retention(RetentionPolicy.RUNTIME) @interface TestConfiguration { @@ -3082,20 +3049,10 @@ public void handleMappedWithDifferentPathAndValueAttributes() { 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 @@ static class DefaultOverrideExplicitAliasRootMetaMetaClass { } @Retention(RetentionPolicy.RUNTIME) - static @interface ValueAttribute { + @interface ValueAttribute { String[] value(); @@ -3552,7 +3509,7 @@ static class DefaultOverrideExplicitAliasRootMetaMetaClass { @Retention(RetentionPolicy.RUNTIME) @ValueAttribute("FromValueAttributeMeta") - static @interface ValueAttributeMeta { + @interface ValueAttributeMeta { String[] value() default {}; @@ -3560,7 +3517,7 @@ static class DefaultOverrideExplicitAliasRootMetaMetaClass { @Retention(RetentionPolicy.RUNTIME) @ValueAttributeMeta("FromValueAttributeMetaMeta") - static @interface ValueAttributeMetaMeta { + @interface ValueAttributeMetaMeta { } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java index 02c624913895..d33e8548b0f4 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java @@ -560,7 +560,6 @@ public Map findSessions(String userName) { } return map; } - } } diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index dbface9e5451..f44b3148220d 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -109,7 +109,7 @@ public class MediaType extends MimeType implements Serializable { /** * Public constant media type for {@code application/json;charset=UTF-8}. - * @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_JSON} + * @deprecated as of 5.2 in favor of {@link #APPLICATION_JSON} * since major browsers like Chrome * * now comply with the specification and interpret correctly UTF-8 special @@ -120,7 +120,7 @@ public class MediaType extends MimeType implements Serializable { /** * A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}. - * @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_JSON_VALUE} + * @deprecated as of 5.2 in favor of {@link #APPLICATION_JSON_VALUE} * since major browsers like Chrome * * now comply with the specification and interpret correctly UTF-8 special @@ -170,7 +170,7 @@ public class MediaType extends MimeType implements Serializable { * @since 5.0 * @see * Problem Details for HTTP APIs, 6.1. application/problem+json - * @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON} + * @deprecated as of 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON} * since major browsers like Chrome * * now comply with the specification and interpret correctly UTF-8 special @@ -182,7 +182,7 @@ public class MediaType extends MimeType implements Serializable { /** * A String equivalent of {@link MediaType#APPLICATION_PROBLEM_JSON_UTF8}. * @since 5.0 - * @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON_VALUE} + * @deprecated as of 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON_VALUE} * since major browsers like Chrome * * now comply with the specification and interpret correctly UTF-8 special diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java index 36d2319f0334..4e341a9d0ed0 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java @@ -221,7 +221,7 @@ private Object unmarshal(List events, Class outputClass) { } } - private Unmarshaller initUnmarshaller(Class outputClass) throws JAXBException { + private Unmarshaller initUnmarshaller(Class outputClass) throws CodecException, JAXBException { Unmarshaller unmarshaller = this.jaxbContexts.createUnmarshaller(outputClass); return this.unmarshallerProcessor.apply(unmarshaller); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java index c48869e6b9a5..150ad691f2e4 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java @@ -140,7 +140,7 @@ public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, } } - private Marshaller initMarshaller(Class clazz) throws JAXBException { + private Marshaller initMarshaller(Class clazz) throws CodecException, JAXBException { Marshaller marshaller = this.jaxbContexts.createMarshaller(clazz); marshaller.setProperty(Marshaller.JAXB_ENCODING, StandardCharsets.UTF_8.name()); marshaller = this.marshallerProcessor.apply(marshaller); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java index 2c205c1ddebc..49441c498c38 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +24,13 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; -import org.springframework.util.Assert; +import org.springframework.core.codec.CodecException; /** * Holder for {@link JAXBContext} instances. * * @author Arjen Poutsma + * @author Juergen Hoeller * @since 5.0 */ final class JaxbContextContainer { @@ -37,24 +38,26 @@ final class JaxbContextContainer { private final ConcurrentMap, JAXBContext> jaxbContexts = new ConcurrentHashMap<>(64); - public Marshaller createMarshaller(Class clazz) throws JAXBException { + public Marshaller createMarshaller(Class clazz) throws CodecException, JAXBException { JAXBContext jaxbContext = getJaxbContext(clazz); return jaxbContext.createMarshaller(); } - public Unmarshaller createUnmarshaller(Class clazz) throws JAXBException { + public Unmarshaller createUnmarshaller(Class clazz) throws CodecException, JAXBException { JAXBContext jaxbContext = getJaxbContext(clazz); return jaxbContext.createUnmarshaller(); } - private JAXBContext getJaxbContext(Class clazz) throws JAXBException { - Assert.notNull(clazz, "Class must not be null"); - JAXBContext jaxbContext = this.jaxbContexts.get(clazz); - if (jaxbContext == null) { - jaxbContext = JAXBContext.newInstance(clazz); - this.jaxbContexts.putIfAbsent(clazz, jaxbContext); - } - return jaxbContext; + private JAXBContext getJaxbContext(Class clazz) throws CodecException { + return this.jaxbContexts.computeIfAbsent(clazz, key -> { + try { + return JAXBContext.newInstance(clazz); + } + catch (JAXBException ex) { + throw new CodecException( + "Could not create JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex); + } + }); } } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java index 913839b001df..811536c31657 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import javax.xml.bind.Unmarshaller; import org.springframework.http.converter.HttpMessageConversionException; -import org.springframework.util.Assert; /** * Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} @@ -106,19 +105,15 @@ protected void customizeUnmarshaller(Unmarshaller unmarshaller) { * @throws HttpMessageConversionException in case of JAXB errors */ protected final JAXBContext getJaxbContext(Class clazz) { - Assert.notNull(clazz, "Class must not be null"); - JAXBContext jaxbContext = this.jaxbContexts.get(clazz); - if (jaxbContext == null) { + return this.jaxbContexts.computeIfAbsent(clazz, key -> { try { - jaxbContext = JAXBContext.newInstance(clazz); - this.jaxbContexts.putIfAbsent(clazz, jaxbContext); + return JAXBContext.newInstance(clazz); } catch (JAXBException ex) { throw new HttpMessageConversionException( - "Could not instantiate JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex); + "Could not create JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex); } - } - return jaxbContext; + }); } }