Remove convention-based annotation attribute override support
This commit completely removes all support for convention-based annotation attribute overrides in Spring's annotation utilities and the MergedAnnotations infrastructure. Composed annotations must now use @AliasFor to declare explicit overrides for attributes in meta-annotations. See gh-28760 Closes gh-28761
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -37,7 +37,6 @@ import javax.annotation.meta.When;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -54,7 +53,6 @@ import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.springframework.core.annotation.AnnotatedElementUtils.findAllMergedAnnotations;
|
||||
import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
|
||||
import static org.springframework.core.annotation.AnnotatedElementUtils.getAllAnnotationAttributes;
|
||||
@@ -94,31 +92,18 @@ class AnnotatedElementUtilsTests {
|
||||
AnnotationAttributes attributes = getMergedAnnotationAttributes(element, name);
|
||||
|
||||
assertThat(attributes).as("Should find @ContextConfig on " + element.getSimpleName()).isNotNull();
|
||||
assertThat(attributes.getStringArray("locations")).as("locations").containsExactly("explicitDeclaration");
|
||||
assertThat(attributes.getStringArray("value")).as("value").containsExactly("explicitDeclaration");
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "explicitDeclaration".
|
||||
assertThat(attributes.getStringArray("locations")).as("locations").isEmpty();
|
||||
assertThat(attributes.getStringArray("value")).as("value").isEmpty();
|
||||
|
||||
// Verify contracts between utility methods:
|
||||
assertThat(isAnnotated(element, name)).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test should never pass, simply because Spring does not support a hybrid
|
||||
* approach for annotation attribute overrides with transitive implicit aliases.
|
||||
* See SPR-13554 for details.
|
||||
* <p>Furthermore, if you choose to execute this test, it can fail for either
|
||||
* the first test class or the second one (with different exceptions), depending
|
||||
* on the order in which the JVM returns the attribute methods via reflection.
|
||||
*/
|
||||
@Disabled("Permanently disabled but left in place for illustrative purposes")
|
||||
@Test
|
||||
void getMergedAnnotationAttributesWithHalfConventionBasedAndHalfAliasedComposedAnnotation() {
|
||||
for (Class<?> clazz : asList(HalfConventionBasedAndHalfAliasedComposedContextConfigClassV1.class,
|
||||
HalfConventionBasedAndHalfAliasedComposedContextConfigClassV2.class)) {
|
||||
getMergedAnnotationAttributesWithHalfConventionBasedAndHalfAliasedComposedAnnotation(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
private void getMergedAnnotationAttributesWithHalfConventionBasedAndHalfAliasedComposedAnnotation(Class<?> clazz) {
|
||||
void getMergedAnnotationAttributesWithHalfConventionBasedAndHalfAliasedComposedAnnotationV1() {
|
||||
Class<?> clazz = HalfConventionBasedAndHalfAliasedComposedContextConfigClassV1.class;
|
||||
String name = ContextConfig.class.getName();
|
||||
String simpleName = clazz.getSimpleName();
|
||||
AnnotationAttributes attributes = getMergedAnnotationAttributes(clazz, name);
|
||||
@@ -134,18 +119,27 @@ class AnnotatedElementUtilsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMergedAnnotationAttributesWithInvalidConventionBasedComposedAnnotation() {
|
||||
Class<?> element = InvalidConventionBasedComposedContextConfigClass.class;
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() ->
|
||||
getMergedAnnotationAttributes(element, ContextConfig.class))
|
||||
.withMessageContaining("Different @AliasFor mirror values for annotation")
|
||||
.withMessageContaining("attribute 'locations' and its alias 'value'")
|
||||
.withMessageContaining("values of [{requiredLocationsDeclaration}] and [{duplicateDeclaration}]");
|
||||
void getMergedAnnotationAttributesWithHalfConventionBasedAndHalfAliasedComposedAnnotationV2() {
|
||||
Class<?> clazz = HalfConventionBasedAndHalfAliasedComposedContextConfigClassV2.class;
|
||||
String name = ContextConfig.class.getName();
|
||||
String simpleName = clazz.getSimpleName();
|
||||
AnnotationAttributes attributes = getMergedAnnotationAttributes(clazz, name);
|
||||
|
||||
assertThat(attributes).as("Should find @ContextConfig on " + simpleName).isNotNull();
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "explicitDeclaration".
|
||||
assertThat(attributes.getStringArray("locations")).as("locations for class [" + simpleName + "]").isEmpty();
|
||||
assertThat(attributes.getStringArray("value")).as("value for class [" + simpleName + "]").isEmpty();
|
||||
|
||||
// Verify contracts between utility methods:
|
||||
assertThat(isAnnotated(clazz, name)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findMergedAnnotationAttributesWithSingleElementOverridingAnArrayViaConvention() {
|
||||
assertComponentScanAttributes(ConventionBasedSinglePackageComponentScanClass.class, "com.example.app.test");
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "com.example.app.test".
|
||||
assertComponentScanAttributes(ConventionBasedSinglePackageComponentScanClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -157,12 +151,16 @@ class AnnotatedElementUtilsTests {
|
||||
assertThat(contextConfig.locations()).as("locations for " + element).isEmpty();
|
||||
// 'value' in @SpringAppConfig should not override 'value' in @ContextConfig
|
||||
assertThat(contextConfig.value()).as("value for " + element).isEmpty();
|
||||
assertThat(contextConfig.classes()).as("classes for " + element).containsExactly(Number.class);
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect Number.class.
|
||||
assertThat(contextConfig.classes()).as("classes for " + element).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findMergedAnnotationWithSingleElementOverridingAnArrayViaConvention() throws Exception {
|
||||
assertWebMapping(WebController.class.getMethod("postMappedWithPathAttribute"));
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "/test".
|
||||
assertWebMapping(WebController.class.getMethod("postMappedWithPathAttribute"), "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -831,15 +829,15 @@ class AnnotatedElementUtilsTests {
|
||||
|
||||
@Test
|
||||
void findMergedAnnotationWithSingleElementOverridingAnArrayViaAliasFor() throws Exception {
|
||||
assertWebMapping(WebController.class.getMethod("getMappedWithValueAttribute"));
|
||||
assertWebMapping(WebController.class.getMethod("getMappedWithPathAttribute"));
|
||||
assertWebMapping(WebController.class.getMethod("getMappedWithValueAttribute"), "/test");
|
||||
assertWebMapping(WebController.class.getMethod("getMappedWithPathAttribute"), "/test");
|
||||
}
|
||||
|
||||
private void assertWebMapping(AnnotatedElement element) {
|
||||
private void assertWebMapping(AnnotatedElement element, String expectedPath) {
|
||||
WebMapping webMapping = findMergedAnnotation(element, WebMapping.class);
|
||||
assertThat(webMapping).isNotNull();
|
||||
assertThat(webMapping.value()).as("value attribute: ").isEqualTo(asArray("/test"));
|
||||
assertThat(webMapping.path()).as("path attribute: ").isEqualTo(asArray("/test"));
|
||||
assertThat(webMapping.value()).as("value attribute: ").isEqualTo(asArray(expectedPath));
|
||||
assertThat(webMapping.path()).as("path attribute: ").isEqualTo(asArray(expectedPath));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1090,8 +1088,7 @@ class AnnotatedElementUtilsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ConventionBasedComposedContextConfig {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfig.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String[] locations() default {};
|
||||
}
|
||||
|
||||
@@ -1099,8 +1096,7 @@ class AnnotatedElementUtilsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface InvalidConventionBasedComposedContextConfig {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfig.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String[] locations();
|
||||
}
|
||||
|
||||
@@ -1258,13 +1254,11 @@ class AnnotatedElementUtilsTests {
|
||||
@AliasFor(annotation = ContextConfig.class, attribute = "locations")
|
||||
String[] locations() default {};
|
||||
|
||||
// Do NOT use @AliasFor(annotation = ...) here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfig.class, attribute = "classes")
|
||||
// Do NOT use @AliasFor(annotation = ...)
|
||||
@AliasFor("value")
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
// Do NOT use @AliasFor(annotation = ...) here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfig.class, attribute = "classes")
|
||||
// Do NOT use @AliasFor(annotation = ...)
|
||||
@AliasFor("classes")
|
||||
Class<?>[] value() default {};
|
||||
}
|
||||
@@ -1303,8 +1297,7 @@ class AnnotatedElementUtilsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ConventionBasedSinglePackageComponentScan {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ComponentScan.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String basePackages();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -279,12 +279,6 @@ class AnnotationTypeMappingsTests {
|
||||
assertThat(getAliasMapping(mapping, 0)).isEqualTo(Mapped.class.getDeclaredMethod("alias"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getConventionMappingReturnsAttributes() throws Exception {
|
||||
AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(Mapped.class).get(1);
|
||||
assertThat(getConventionMapping(mapping, 1)).isEqualTo(Mapped.class.getDeclaredMethod("convention"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMirrorSetWhenAliasPairReturnsMirrors() {
|
||||
AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(AliasPair.class).get(0);
|
||||
@@ -410,14 +404,6 @@ class AnnotationTypeMappingsTests {
|
||||
assertThat(getAliasMapping(mappingsC, 1).getName()).isEqualTo("a1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getConventionMappingWhenConventionToExplicitAliasesReturnsMappedAttributes() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(ConventionToExplicitAliases.class);
|
||||
AnnotationTypeMapping mapping = getMapping(mappings, ConventionToExplicitAliasesTarget.class);
|
||||
assertThat(mapping.getConventionMapping(0)).isEqualTo(0);
|
||||
assertThat(mapping.getConventionMapping(1)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEquivalentToDefaultValueWhenValueAndDefaultAreNullReturnsTrue() {
|
||||
AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(ClassValue.class).get(0);
|
||||
@@ -481,11 +467,6 @@ class AnnotationTypeMappingsTests {
|
||||
return mapped != -1 ? mapping.getRoot().getAttributes().get(mapped) : null;
|
||||
}
|
||||
|
||||
private @Nullable Method getConventionMapping(AnnotationTypeMapping mapping, int attributeIndex) {
|
||||
int mapped = mapping.getConventionMapping(attributeIndex);
|
||||
return mapped != -1 ? mapping.getRoot().getAttributes().get(mapped) : null;
|
||||
}
|
||||
|
||||
private AnnotationTypeMapping getMapping(AnnotationTypeMappings mappings,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
|
||||
@@ -890,23 +871,6 @@ class AnnotationTypeMappingsTests {
|
||||
String a1() default "";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ConventionToExplicitAliasesTarget {
|
||||
|
||||
@AliasFor("test")
|
||||
String value() default "";
|
||||
|
||||
@AliasFor("value")
|
||||
String test() default "";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ConventionToExplicitAliasesTarget
|
||||
@interface ConventionToExplicitAliases {
|
||||
|
||||
String test() default "";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ClassValue {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -1362,8 +1362,7 @@ class AnnotationUtilsTests {
|
||||
@WebMapping(method = RequestMethod.POST, name = "")
|
||||
@interface Post {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = WebMapping.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String path() default "";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -63,8 +63,8 @@ import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link MergedAnnotations} and {@link MergedAnnotation}. These tests
|
||||
* cover common usage scenarios and were mainly ported from the original
|
||||
* {@code AnnotationUtils} and {@code AnnotatedElementUtils} tests.
|
||||
* cover common usage scenarios and were mainly ported from the original tests in
|
||||
* {@link AnnotationUtilsTests} and {@link AnnotatedElementUtilsTests}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Rod Johnson
|
||||
@@ -218,8 +218,10 @@ class MergedAnnotationsTests {
|
||||
MergedAnnotations.from(ConventionBasedComposedContextConfigurationClass.class,
|
||||
SearchStrategy.INHERITED_ANNOTATIONS).get(ContextConfiguration.class);
|
||||
assertThat(annotation.isPresent()).isTrue();
|
||||
assertThat(annotation.getStringArray("locations")).containsExactly("explicitDeclaration");
|
||||
assertThat(annotation.getStringArray("value")).containsExactly("explicitDeclaration");
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "explicitDeclaration".
|
||||
assertThat(annotation.getStringArray("locations")).isEmpty();
|
||||
assertThat(annotation.getStringArray("value")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -244,16 +246,11 @@ class MergedAnnotationsTests {
|
||||
assertThat(annotation.getStringArray("value")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWithInheritedAnnotationsFromInvalidConventionBasedComposedAnnotation() {
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class)
|
||||
.isThrownBy(() -> MergedAnnotations.from(InvalidConventionBasedComposedContextConfigurationClass.class,
|
||||
SearchStrategy.INHERITED_ANNOTATIONS).get(ContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWithTypeHierarchyWithSingleElementOverridingAnArrayViaConvention() {
|
||||
testGetWithTypeHierarchy(ConventionBasedSinglePackageComponentScanClass.class, "com.example.app.test");
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "com.example.app.test".
|
||||
testGetWithTypeHierarchy(ConventionBasedSinglePackageComponentScanClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -263,12 +260,16 @@ class MergedAnnotationsTests {
|
||||
.get(ContextConfiguration.class);
|
||||
assertThat(annotation.getStringArray("locations")).isEmpty();
|
||||
assertThat(annotation.getStringArray("value")).isEmpty();
|
||||
assertThat(annotation.getClassArray("classes")).containsExactly(Number.class);
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect Number.class.
|
||||
assertThat(annotation.getClassArray("classes")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWithTypeHierarchyOnMethodWithSingleElementOverridingAnArrayViaConvention() throws Exception {
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("postMappedWithPathAttribute"));
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "/test".
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("postMappedWithPathAttribute"), "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,15 +782,15 @@ class MergedAnnotationsTests {
|
||||
|
||||
@Test
|
||||
void getWithTypeHierarchyOnMethodWithSingleElementOverridingAnArrayViaAliasFor() throws Exception {
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("getMappedWithValueAttribute"));
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("getMappedWithPathAttribute"));
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("getMappedWithValueAttribute"), "/test");
|
||||
testGetWithTypeHierarchyWebMapping(WebController.class.getMethod("getMappedWithPathAttribute"), "/test");
|
||||
}
|
||||
|
||||
private void testGetWithTypeHierarchyWebMapping(AnnotatedElement element) {
|
||||
private void testGetWithTypeHierarchyWebMapping(AnnotatedElement element, String expectedPath) {
|
||||
MergedAnnotation<?> annotation = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(RequestMapping.class);
|
||||
assertThat(annotation.getStringArray("value")).containsExactly("/test");
|
||||
assertThat(annotation.getStringArray("path")).containsExactly("/test");
|
||||
assertThat(annotation.getStringArray("value")).containsExactly(expectedPath);
|
||||
assertThat(annotation.getStringArray("path")).containsExactly(expectedPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2160,9 +2161,11 @@ class MergedAnnotationsTests {
|
||||
|
||||
@Test
|
||||
void getValueWhenHasDefaultOverride() {
|
||||
MergedAnnotation<?> annotation = MergedAnnotations.from(DefaultOverrideClass.class)
|
||||
.get(DefaultOverrideRoot.class);
|
||||
assertThat(annotation.getString("text")).isEqualTo("metameta");
|
||||
MergedAnnotation<?> annotation =
|
||||
MergedAnnotations.from(DefaultOverrideClass.class).get(DefaultOverrideRoot.class);
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "metameta".
|
||||
assertThat(annotation.getString("text")).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test // gh-22654
|
||||
@@ -2370,24 +2373,13 @@ class MergedAnnotationsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ConventionBasedComposedContextConfiguration {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String[] locations() default {};
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class)
|
||||
// Do NOT use @AliasFor here
|
||||
Class<?>[] classes() default {};
|
||||
}
|
||||
|
||||
@ContextConfiguration(value = "duplicateDeclaration")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface InvalidConventionBasedComposedContextConfiguration {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class)
|
||||
String[] locations();
|
||||
}
|
||||
|
||||
/**
|
||||
* This hybrid approach for annotation attribute overrides with transitive implicit
|
||||
* aliases is unsupported. See SPR-13554 for details.
|
||||
@@ -2396,8 +2388,7 @@ class MergedAnnotationsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface HalfConventionBasedAndHalfAliasedComposedContextConfiguration {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String[] locations() default {};
|
||||
|
||||
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
|
||||
@@ -2519,13 +2510,11 @@ class MergedAnnotationsTests {
|
||||
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
|
||||
String[] locations() default {};
|
||||
|
||||
// Do NOT use @AliasFor(annotation = ...) here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class, attribute = "classes")
|
||||
// Do NOT use @AliasFor(annotation = ...)
|
||||
@AliasFor("value")
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
// Do NOT use @AliasFor(annotation = ...) here until Spring 6.1
|
||||
// @AliasFor(annotation = ContextConfiguration.class, attribute = "classes")
|
||||
// Do NOT use @AliasFor(annotation = ...)
|
||||
@AliasFor("classes")
|
||||
Class<?>[] value() default {};
|
||||
}
|
||||
@@ -2562,8 +2551,7 @@ class MergedAnnotationsTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ConventionBasedSinglePackageComponentScan {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ComponentScan.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String basePackages();
|
||||
}
|
||||
|
||||
@@ -2698,10 +2686,6 @@ class MergedAnnotationsTests {
|
||||
static class ConventionBasedComposedContextConfigurationClass {
|
||||
}
|
||||
|
||||
@InvalidConventionBasedComposedContextConfiguration(locations = "requiredLocationsDeclaration")
|
||||
static class InvalidConventionBasedComposedContextConfigurationClass {
|
||||
}
|
||||
|
||||
@HalfConventionBasedAndHalfAliasedComposedContextConfiguration(xmlConfigFiles = "explicitDeclaration")
|
||||
static class HalfConventionBasedAndHalfAliasedComposedContextConfigurationClass1 {
|
||||
}
|
||||
@@ -3153,8 +3137,7 @@ class MergedAnnotationsTests {
|
||||
@RequestMapping(method = RequestMethod.POST, name = "")
|
||||
@interface PostMapping {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = RequestMapping.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String path() default "";
|
||||
}
|
||||
|
||||
@@ -3645,13 +3628,11 @@ class MergedAnnotationsTests {
|
||||
@interface DefaultOverrideRoot {
|
||||
|
||||
String text() default "root";
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@DefaultOverrideRoot
|
||||
@interface DefaultOverrideMeta {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -3659,18 +3640,15 @@ class MergedAnnotationsTests {
|
||||
@interface DefaultOverrideMetaMeta {
|
||||
|
||||
String text() default "metameta";
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@DefaultOverrideMetaMeta
|
||||
@interface DefaultOverrideMetaMetaMeta {
|
||||
|
||||
}
|
||||
|
||||
@DefaultOverrideMetaMetaMeta
|
||||
static class DefaultOverrideClass {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -33,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* for a much more extensive collection of tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class TypeMappedAnnotationTests {
|
||||
|
||||
@@ -62,11 +63,19 @@ class TypeMappedAnnotationTests {
|
||||
@Test
|
||||
void mappingConventionAliasToMetaAnnotationReturnsMappedValues() {
|
||||
TypeMappedAnnotation<?> annotation = getTypeMappedAnnotation(
|
||||
WithConventionAliasToMetaAnnotation.class,
|
||||
ConventionAliasToMetaAnnotation.class);
|
||||
assertThat(annotation.getString("value")).isEqualTo("value");
|
||||
assertThat(annotation.getString("convention")).isEqualTo("convention");
|
||||
|
||||
annotation = getTypeMappedAnnotation(
|
||||
WithConventionAliasToMetaAnnotation.class,
|
||||
ConventionAliasToMetaAnnotation.class,
|
||||
ConventionAliasMetaAnnotationTarget.class);
|
||||
assertThat(annotation.getString("value")).isEmpty();
|
||||
assertThat(annotation.getString("convention")).isEqualTo("convention");
|
||||
// Convention-based annotation attribute overrides are no longer supported as of
|
||||
// Spring Framework 7.0. Otherwise, we would expect "convention".
|
||||
assertThat(annotation.getString("convention")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,8 +204,7 @@ class TypeMappedAnnotationTests {
|
||||
|
||||
String value() default "";
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = ConventionAliasMetaAnnotationTarget.class)
|
||||
// Do NOT use @AliasFor here
|
||||
String convention() default "";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -665,8 +665,7 @@ class AnnotationMetadataTests {
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface ComposedConfigurationWithAttributeOverrides {
|
||||
|
||||
// Do NOT use @AliasFor here until Spring 6.1
|
||||
// @AliasFor(annotation = TestComponentScan.class)
|
||||
@AliasFor(annotation = TestComponentScan.class)
|
||||
String[] basePackages() default {};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user