From 0e861af0502e7dc7622f574e496652013c3f08a6 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 17 Oct 2022 16:52:17 +0200 Subject: [PATCH] Log warning for convention-based attribute overrides once per annotation type See gh-28760, gh-29206 --- .../annotation/AnnotationTypeMapping.java | 28 +++++++++---------- .../annotation/MergedAnnotationsTests.java | 4 +++ 2 files changed, 18 insertions(+), 14 deletions(-) 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 05a9cc7ea3b..50077298307 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 @@ -53,9 +53,8 @@ final class AnnotationTypeMapping { private static final Log logger = LogFactory.getLog(AnnotationTypeMapping.class); /** - * Set of fully qualified class names concatenated with attribute names for - * annotations which we have already checked for use of convention-based - * annotation attribute overrides. + * Set of fully qualified class names for annotations which we have already + * checked for use of convention-based annotation attribute overrides. * @since 6.0 * @see #addConventionMappings() */ @@ -284,21 +283,12 @@ final class AnnotationTypeMapping { } AttributeMethods rootAttributes = this.root.getAttributes(); int[] mappings = this.conventionMappings; + Set conventionMappedAttributes = new HashSet<>(); for (int i = 0; i < mappings.length; i++) { String name = this.attributes.get(i).getName(); int mapped = rootAttributes.indexOf(name); if (!MergedAnnotation.VALUE.equals(name) && mapped != -1 && !isExplicitAttributeOverride(name)) { - String rootAnnotationTypeName = this.root.annotationType.getName(); - String cacheKey = rootAnnotationTypeName + "." + name; - // We want to avoid duplicate log warnings as much as possible, without full synchronization. - if (conventionBasedOverrideCheckCache.add(cacheKey) && logger.isWarnEnabled()) { - logger.warn(""" - Support for convention-based annotation attribute overrides is \ - deprecated and will be removed in Spring Framework 6.1. Please \ - annotate the '%s' attribute in @%s with an appropriate @AliasFor \ - declaration -- for example, @AliasFor(annotation = %s.class).""" - .formatted(name, rootAnnotationTypeName, this.annotationType.getName())); - } + conventionMappedAttributes.add(name); mappings[i] = mapped; MirrorSet mirrors = getMirrorSets().getAssigned(i); if (mirrors != null) { @@ -308,6 +298,16 @@ final class AnnotationTypeMapping { } } } + String rootAnnotationTypeName = this.root.annotationType.getName(); + // We want to avoid duplicate log warnings as much as possible, without full synchronization. + if (conventionBasedOverrideCheckCache.add(rootAnnotationTypeName) && + !conventionMappedAttributes.isEmpty() && logger.isWarnEnabled()) { + logger.warn(""" + Support for convention-based annotation attribute overrides is deprecated \ + and will be removed in Spring Framework 6.1. Please annotate the following \ + attributes in @%s with appropriate @AliasFor declarations: %s""" + .formatted(rootAnnotationTypeName, conventionMappedAttributes)); + } } /** 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 e366547fb22..13464390751 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 @@ -2445,6 +2445,10 @@ class MergedAnnotationsTests { // Do NOT use @AliasFor here until Spring 6.1 // @AliasFor(annotation = ContextConfiguration.class) String[] locations() default {}; + + // Do NOT use @AliasFor here until Spring 6.1 + // @AliasFor(annotation = ContextConfiguration.class) + Class[] classes() default {}; } @ContextConfiguration(value = "duplicateDeclaration")