Browse Source

Log warning for convention-based attribute overrides once per annotation type

See gh-28760, gh-29206
pull/29336/head
Sam Brannen 3 years ago
parent
commit
0e861af050
  1. 28
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java
  2. 4
      spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java

28
spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java

@ -53,9 +53,8 @@ final class AnnotationTypeMapping { @@ -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 { @@ -284,21 +283,12 @@ final class AnnotationTypeMapping {
}
AttributeMethods rootAttributes = this.root.getAttributes();
int[] mappings = this.conventionMappings;
Set<String> 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 { @@ -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));
}
}
/**

4
spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java

@ -2445,6 +2445,10 @@ class MergedAnnotationsTests { @@ -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")

Loading…
Cancel
Save