Browse Source

Stop using explicitly aliased `value` attribute as @⁠Component name

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
pull/34399/head
Sam Brannen 11 months ago
parent
commit
7557967f9e
  1. 25
      spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java
  2. 12
      spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java

25
spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java

@ -147,25 +147,16 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator { @@ -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 " +

12
spring-context/src/test/java/org/springframework/context/annotation/AnnotationBeanNameGeneratorTests.java

@ -150,18 +150,14 @@ class AnnotationBeanNameGeneratorTests { @@ -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

Loading…
Cancel
Save