From 7557967f9edce1574b33476defc347de65b74794 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:21:29 +0100 Subject: [PATCH] =?UTF-8?q?Stop=20using=20explicitly=20aliased=20`value`?= =?UTF-8?q?=20attribute=20as=20@=E2=81=A0Component=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to this commit, if a custom stereotype annotation was meta-annotated with @⁠Component and declared a local String `value` attribute that was explicitly configured (via @⁠AliasFor) as an override for an attribute other than @⁠Component.value, the local `value` attribute was still used as a convention-based override for @⁠Component.value. Consequently, a local `value` attribute was used as a custom @⁠Component name, even when that is clearly not the intent. To address that, this commit revises the logic in AnnotationBeanNameGenerator so that a `value` attribute which is explicitly aliased to something other than @⁠Component.value is no longer used as an explicit @⁠Component name. See gh-34317 Closes gh-34346 --- .../AnnotationBeanNameGenerator.java | 25 ++++++------------- .../AnnotationBeanNameGeneratorTests.java | 12 +++------ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index 5c834b1e010..7502db9182e 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -147,25 +147,16 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator { key -> getMetaAnnotationTypes(mergedAnnotation)); if (isStereotypeWithNameValue(annotationType, metaAnnotationTypes, attributes)) { Object value = attributes.get(MergedAnnotation.VALUE); - if (value instanceof String currentName && !currentName.isBlank()) { + if (value instanceof String currentName && !currentName.isBlank() && + !hasExplicitlyAliasedValueAttribute(mergedAnnotation.getType())) { if (conventionBasedStereotypeCheckCache.add(annotationType) && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) && logger.isWarnEnabled()) { - if (hasExplicitlyAliasedValueAttribute(mergedAnnotation.getType())) { - logger.warn(""" - Although the 'value' attribute in @%s declares @AliasFor for an attribute \ - other than @Component's 'value' attribute, the value is still used as the \ - @Component name based on convention. As of Spring Framework 7.0, such a \ - 'value' attribute will no longer be used as the @Component name.""" - .formatted(annotationType)); - } - else { - logger.warn(""" - Support for convention-based @Component names is deprecated and will \ - be removed in a future version of the framework. Please annotate the \ - 'value' attribute in @%s with @AliasFor(annotation=Component.class) \ - to declare an explicit alias for @Component's 'value' attribute.""" - .formatted(annotationType)); - } + logger.warn(""" + Support for convention-based @Component names is deprecated and will \ + be removed in a future version of the framework. Please annotate the \ + 'value' attribute in @%s with @AliasFor(annotation=Component.class) \ + to declare an explicit alias for @Component's 'value' attribute.""" + .formatted(annotationType)); } if (beanName != null && !currentName.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " + diff --git a/spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java index e8174741824..5d2d23b9c9c 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java @@ -150,18 +150,14 @@ class AnnotationBeanNameGeneratorTests { assertGeneratedName(RestControllerAdviceClass.class, "myRestControllerAdvice"); } - @Test // gh-34317 + @Test // gh-34317, gh-34346 void generateBeanNameFromStereotypeAnnotationWithStringValueAsExplicitAliasForMetaAnnotationOtherThanComponent() { - // As of Spring Framework 6.2, "enigma" is incorrectly used as the @Component name. - // As of Spring Framework 7.0, the generated name will be "annotationBeanNameGeneratorTests.StereotypeWithoutExplicitName". - assertGeneratedName(StereotypeWithoutExplicitName.class, "enigma"); + assertGeneratedName(StereotypeWithoutExplicitName.class, "annotationBeanNameGeneratorTests.StereotypeWithoutExplicitName"); } - @Test // gh-34317 + @Test // gh-34317, gh-34346 void generateBeanNameFromStereotypeAnnotationWithStringValueAndExplicitAliasForComponentNameWithBlankName() { - // As of Spring Framework 6.2, "enigma" is incorrectly used as the @Component name. - // As of Spring Framework 7.0, the generated name will be "annotationBeanNameGeneratorTests.StereotypeWithGeneratedName". - assertGeneratedName(StereotypeWithGeneratedName.class, "enigma"); + assertGeneratedName(StereotypeWithGeneratedName.class, "annotationBeanNameGeneratorTests.StereotypeWithGeneratedName"); } @Test // gh-34317