1
1
/*
2
- * Copyright 2002-2023 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
28
28
import java .util .List ;
29
29
import java .util .Map ;
30
30
import java .util .Set ;
31
- import java .util .concurrent .ConcurrentHashMap ;
32
- import java .util .function .Predicate ;
33
31
34
- import org .apache .commons .logging .Log ;
35
- import org .apache .commons .logging .LogFactory ;
36
32
import org .jspecify .annotations .Nullable ;
37
33
38
34
import org .springframework .core .annotation .AnnotationTypeMapping .MirrorSets .MirrorSet ;
51
47
*/
52
48
final class AnnotationTypeMapping {
53
49
54
- private static final Log logger = LogFactory .getLog (AnnotationTypeMapping .class );
55
-
56
- private static final Predicate <? super Annotation > isBeanValidationConstraint = annotation ->
57
- annotation .annotationType ().getName ().equals ("jakarta.validation.Constraint" );
58
-
59
- /**
60
- * Set used to track which convention-based annotation attribute overrides
61
- * have already been checked. Each key is the combination of the fully
62
- * qualified class name of a composed annotation and a meta-annotation
63
- * that it is either present or meta-present on the composed annotation,
64
- * separated by a dash.
65
- * @since 6.0
66
- * @see #addConventionMappings()
67
- */
68
- private static final Set <String > conventionBasedOverrideCheckCache = ConcurrentHashMap .newKeySet ();
69
-
70
50
private static final MirrorSet [] EMPTY_MIRROR_SETS = new MirrorSet [0 ];
71
51
72
52
private static final int [] EMPTY_INT_ARRAY = new int [0 ];
@@ -90,8 +70,6 @@ final class AnnotationTypeMapping {
90
70
91
71
private final int [] aliasMappings ;
92
72
93
- private final int [] conventionMappings ;
94
-
95
73
private final int [] annotationValueMappings ;
96
74
97
75
private final AnnotationTypeMapping [] annotationValueSource ;
@@ -117,13 +95,10 @@ final class AnnotationTypeMapping {
117
95
this .attributes = AttributeMethods .forAnnotationType (annotationType );
118
96
this .mirrorSets = new MirrorSets ();
119
97
this .aliasMappings = filledIntArray (this .attributes .size ());
120
- this .conventionMappings = filledIntArray (this .attributes .size ());
121
98
this .annotationValueMappings = filledIntArray (this .attributes .size ());
122
99
this .annotationValueSource = new AnnotationTypeMapping [this .attributes .size ()];
123
100
this .aliasedBy = resolveAliasedForTargets ();
124
101
processAliases ();
125
- addConventionMappings ();
126
- addConventionAnnotationValues ();
127
102
this .synthesizable = computeSynthesizableFlag (visitedAnnotationTypes );
128
103
}
129
104
@@ -284,95 +259,6 @@ private int getFirstRootAttributeIndex(Collection<Method> aliases) {
284
259
return -1 ;
285
260
}
286
261
287
- private void addConventionMappings () {
288
- if (this .distance == 0 ) {
289
- return ;
290
- }
291
- AttributeMethods rootAttributes = this .root .getAttributes ();
292
- int [] mappings = this .conventionMappings ;
293
- Set <String > conventionMappedAttributes = new HashSet <>();
294
- for (int i = 0 ; i < mappings .length ; i ++) {
295
- String name = this .attributes .get (i ).getName ();
296
- int mapped = rootAttributes .indexOf (name );
297
- if (!MergedAnnotation .VALUE .equals (name ) && mapped != -1 && !isExplicitAttributeOverride (name )) {
298
- conventionMappedAttributes .add (name );
299
- mappings [i ] = mapped ;
300
- MirrorSet mirrors = getMirrorSets ().getAssigned (i );
301
- if (mirrors != null ) {
302
- for (int j = 0 ; j < mirrors .size (); j ++) {
303
- mappings [mirrors .getAttributeIndex (j )] = mapped ;
304
- }
305
- }
306
- }
307
- }
308
- String rootAnnotationTypeName = this .root .annotationType .getName ();
309
- String cacheKey = rootAnnotationTypeName + '-' + this .annotationType .getName ();
310
- // We want to avoid duplicate log warnings as much as possible, without full synchronization,
311
- // and we intentionally invoke add() before checking if any convention-based overrides were
312
- // actually encountered in order to ensure that we add a "tracked" entry for the current cache
313
- // key in any case.
314
- // In addition, we do NOT want to log warnings for custom Java Bean Validation constraint
315
- // annotations that are meta-annotated with other constraint annotations -- for example,
316
- // @org.hibernate.validator.constraints.URL which overrides attributes in
317
- // @jakarta.validation.constraints.Pattern.
318
- if (conventionBasedOverrideCheckCache .add (cacheKey ) && !conventionMappedAttributes .isEmpty () &&
319
- Arrays .stream (this .annotationType .getAnnotations ()).noneMatch (isBeanValidationConstraint ) &&
320
- logger .isWarnEnabled ()) {
321
- logger .warn ("""
322
- Support for convention-based annotation attribute overrides is deprecated \
323
- and will be removed in Spring Framework 7.0. Please annotate the following \
324
- attributes in @%s with appropriate @AliasFor declarations: %s"""
325
- .formatted (rootAnnotationTypeName , conventionMappedAttributes ));
326
- }
327
- }
328
-
329
- /**
330
- * Determine if the given annotation attribute in the {@linkplain #getRoot()
331
- * root annotation} is an explicit annotation attribute override for an
332
- * attribute in a meta-annotation, explicit in the sense that the override
333
- * is declared via {@link AliasFor @AliasFor}.
334
- * <p>If the named attribute does not exist in the root annotation, this
335
- * method returns {@code false}.
336
- * @param name the name of the annotation attribute to check
337
- * @since 6.0
338
- */
339
- private boolean isExplicitAttributeOverride (String name ) {
340
- Method attribute = this .root .getAttributes ().get (name );
341
- if (attribute != null ) {
342
- AliasFor aliasFor = AnnotationsScanner .getDeclaredAnnotation (attribute , AliasFor .class );
343
- return ((aliasFor != null ) &&
344
- (aliasFor .annotation () != Annotation .class ) &&
345
- (aliasFor .annotation () != this .root .annotationType ));
346
- }
347
- return false ;
348
- }
349
-
350
- private void addConventionAnnotationValues () {
351
- for (int i = 0 ; i < this .attributes .size (); i ++) {
352
- Method attribute = this .attributes .get (i );
353
- boolean isValueAttribute = MergedAnnotation .VALUE .equals (attribute .getName ());
354
- AnnotationTypeMapping mapping = this ;
355
- while (mapping != null && mapping .distance > 0 ) {
356
- int mapped = mapping .getAttributes ().indexOf (attribute .getName ());
357
- if (mapped != -1 && isBetterConventionAnnotationValue (i , isValueAttribute , mapping )) {
358
- this .annotationValueMappings [i ] = mapped ;
359
- this .annotationValueSource [i ] = mapping ;
360
- }
361
- mapping = mapping .source ;
362
- }
363
- }
364
- }
365
-
366
- private boolean isBetterConventionAnnotationValue (int index , boolean isValueAttribute ,
367
- AnnotationTypeMapping mapping ) {
368
-
369
- if (this .annotationValueMappings [index ] == -1 ) {
370
- return true ;
371
- }
372
- int existingDistance = this .annotationValueSource [index ].distance ;
373
- return !isValueAttribute && existingDistance > mapping .distance ;
374
- }
375
-
376
262
@ SuppressWarnings ("unchecked" )
377
263
private boolean computeSynthesizableFlag (Set <Class <? extends Annotation >> visitedAnnotationTypes ) {
378
264
// Track that we have visited the current annotation type.
@@ -390,13 +276,6 @@ private boolean computeSynthesizableFlag(Set<Class<? extends Annotation>> visite
390
276
return true ;
391
277
}
392
278
393
- // Uses convention-based attribute overrides in meta-annotations?
394
- for (int index : this .conventionMappings ) {
395
- if (index != -1 ) {
396
- return true ;
397
- }
398
- }
399
-
400
279
// Has nested annotations or arrays of annotations that are synthesizable?
401
280
if (getAttributes ().hasNestedAnnotation ()) {
402
281
AttributeMethods attributeMethods = getAttributes ();
@@ -532,18 +411,6 @@ int getAliasMapping(int attributeIndex) {
532
411
return this .aliasMappings [attributeIndex ];
533
412
}
534
413
535
- /**
536
- * Get the related index of a convention mapped attribute, or {@code -1}
537
- * if there is no mapping. The resulting value is the index of the attribute
538
- * on the root annotation that can be invoked in order to obtain the actual
539
- * value.
540
- * @param attributeIndex the attribute index of the source attribute
541
- * @return the mapped attribute index or {@code -1}
542
- */
543
- int getConventionMapping (int attributeIndex ) {
544
- return this .conventionMappings [attributeIndex ];
545
- }
546
-
547
414
/**
548
415
* Get a mapped attribute value from the most suitable
549
416
* {@link #getAnnotation() meta-annotation}.
0 commit comments