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 f1c2e126d32..e2478a7eb94 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 @@ -296,7 +296,7 @@ final class AnnotationTypeMapping { AnnotationTypeMapping mapping = this; while (mapping != null && mapping.distance > 0) { int mapped = mapping.getAttributes().indexOf(attribute.getName()); - if (mapped != -1 && isBetterConventionAnnotationValue(i, isValueAttribute, mapping)) { + if (mapped != -1 && isBetterConventionAnnotationValue(i, isValueAttribute, mapping)) { this.annotationValueMappings[i] = mapped; this.annotationValueSource[i] = mapping; } @@ -307,6 +307,7 @@ final class AnnotationTypeMapping { private boolean isBetterConventionAnnotationValue(int index, boolean isValueAttribute, AnnotationTypeMapping mapping) { + if (this.annotationValueMappings[index] == -1) { return true; } @@ -439,27 +440,27 @@ final class AnnotationTypeMapping { /** * Get a mapped attribute value from the most suitable - * {@link #getAnnotation() meta-annotation}. The resulting value is obtained - * from the closest meta-annotation, taking into consideration both - * convention and alias based mapping rules. For root mappings, this method - * will always return {@code null}. + * {@link #getAnnotation() meta-annotation}. + *

The resulting value is obtained from the closest meta-annotation, + * taking into consideration both convention and alias based mapping rules. + * For root mappings, this method will always return {@code null}. * @param attributeIndex the attribute index of the source attribute * @param metaAnnotationsOnly if only meta annotations should be considered. * If this parameter is {@code false} then aliases within the annotation will - * not be excluded. + * also be considered. * @return the mapped annotation value, or {@code null} */ @Nullable Object getMappedAnnotationValue(int attributeIndex, boolean metaAnnotationsOnly) { - int mapped = this.annotationValueMappings[attributeIndex]; - if (mapped == -1) { + int mappedIndex = this.annotationValueMappings[attributeIndex]; + if (mappedIndex == -1) { return null; } AnnotationTypeMapping source = this.annotationValueSource[attributeIndex]; - if(source == this && metaAnnotationsOnly) { + if (source == this && metaAnnotationsOnly) { return null; } - return ReflectionUtils.invokeMethod(source.attributes.get(mapped), source.annotation); + return ReflectionUtils.invokeMethod(source.attributes.get(mappedIndex), source.annotation); } /** @@ -467,7 +468,7 @@ final class AnnotationTypeMapping { * attribute at the given index. * @param attributeIndex the attribute index of the source attribute * @param value the value to check - * @param valueExtractor the value extractor used to extract value from any + * @param valueExtractor the value extractor used to extract values from any * nested annotations * @return {@code true} if the value is equivalent to the default value */ @@ -533,13 +534,13 @@ final class AnnotationTypeMapping { return value.getName().equals(extractedValue); } - private static boolean areEquivalent(Annotation value, @Nullable Object extractedValue, + private static boolean areEquivalent(Annotation annotation, @Nullable Object extractedValue, BiFunction valueExtractor) { - AttributeMethods attributes = AttributeMethods.forAnnotationType(value.annotationType()); + AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType()); for (int i = 0; i < attributes.size(); i++) { Method attribute = attributes.get(i); - if (!areEquivalent(ReflectionUtils.invokeMethod(attribute, value), + if (!areEquivalent(ReflectionUtils.invokeMethod(attribute, annotation), valueExtractor.apply(attribute, extractedValue), valueExtractor)) { return false; } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java index ebc76304738..2f732df792f 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java @@ -205,9 +205,9 @@ final class AnnotationTypeMappings { } /** - * Return or create {@link AnnotationTypeMappings} for the specified annotation type. + * Get or create {@link AnnotationTypeMappings} for the specified annotation type. * @param annotationType the annotation type - * @return a new or existing {@link AnnotationTypeMapping} instance + * @return a new or existing {@link AnnotationTypeMappings} instance */ AnnotationTypeMappings get(Class annotationType) { return this.mappings.computeIfAbsent(annotationType, this::createMappings); diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java index be62d40d943..3c6498d911e 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java @@ -83,26 +83,28 @@ public interface MergedAnnotation { boolean isPresent(); /** - * Determine if the annotation is directly present on the source. A directly - * present annotation is one that the user has explicitly declared and not - * one that is {@linkplain #isMetaPresent() meta-present} or - * {@link Inherited @Inherited}. + * Determine if the annotation is directly present on the source. + *

A directly present annotation is one that the user has explicitly + * declared and not one that is {@linkplain #isMetaPresent() meta-present} + * or {@link Inherited @Inherited}. * @return {@code true} if the annotation is directly present */ boolean isDirectlyPresent(); /** - * Determine if the annotation is meta-present on the source. A meta-present - * annotation is an annotation that the user hasn't explicitly declared, but - * has been used as a meta-annotation somewhere in the annotation hierarchy. + * Determine if the annotation is meta-present on the source. + *

A meta-present annotation is an annotation that the user hasn't + * explicitly declared, but has been used as a meta-annotation somewhere in + * the annotation hierarchy. * @return {@code true} if the annotation is meta-present */ boolean isMetaPresent(); /** * Get the distance of this annotation related to its use as a - * meta-annotation. A directly declared annotation has a distance of {@code 0}, - * a meta-annotation has a distance of {@code 1}, a meta-annotation on a + * meta-annotation. + *

A directly declared annotation has a distance of {@code 0}, a + * meta-annotation has a distance of {@code 1}, a meta-annotation on a * meta-annotation has a distance of {@code 2}, etc. A {@linkplain #missing() * missing} annotation will always return a distance of {@code -1}. * @return the annotation distance or {@code -1} if the annotation is missing @@ -111,7 +113,7 @@ public interface MergedAnnotation { /** * Get the index of the aggregate collection containing this annotation. - * Can be used to reorder a stream of annotations, for example, to give a + *

Can be used to reorder a stream of annotations, for example, to give a * higher priority to annotations declared on a superclass or interface. A * {@linkplain #missing() missing} annotation will always return an aggregate * index of {@code -1}. @@ -122,11 +124,12 @@ public interface MergedAnnotation { /** * Get the source that ultimately declared the root annotation, or - * {@code null} if the source is not known. If this merged annotation was - * created {@link MergedAnnotations#from(java.lang.reflect.AnnotatedElement) - * from} an {@link AnnotatedElement} then this source will be an element of - * the same type. If the annotation was loaded without using reflection, the - * source can be of any type, but should have a sensible {@code toString()}. + * {@code null} if the source is not known. + *

If this merged annotation was created + * {@link MergedAnnotations#from(AnnotatedElement) from} an + * {@link AnnotatedElement} then this source will be an element of the same + * type. If the annotation was loaded without using reflection, the source + * can be of any type, but should have a sensible {@code toString()}. * Meta-annotations will always return the same source as the * {@link #getRoot() root}. * @return the source, or {@code null} @@ -136,8 +139,8 @@ public interface MergedAnnotation { /** * Get the source of the meta-annotation, or {@code null} if the - * annotation is not {@linkplain #isMetaPresent() meta-present}. The - * meta-source is the annotation that was meta-annotated with this + * annotation is not {@linkplain #isMetaPresent() meta-present}. + *

The meta-source is the annotation that was meta-annotated with this * annotation. * @return the meta-annotation source or {@code null} * @see #getRoot() @@ -154,9 +157,9 @@ public interface MergedAnnotation { MergedAnnotation getRoot(); /** - * Return the complete list of annotation types from this annotation to the - * {@link #getRoot() root}. Provides a useful way to uniquely identify a - * merged annotation instance. + * Get the complete list of annotation types within the annotation hierarchy + * from this annotation to the {@link #getRoot() root}. + *

Provides a useful way to uniquely identify a merged annotation instance. * @return the meta types for the annotation * @see MergedAnnotationPredicates#unique(Function) * @see #getRoot() @@ -458,7 +461,7 @@ public interface MergedAnnotation { AnnotationAttributes asAnnotationAttributes(Adapt... adaptations); /** - * Return an immutable {@link Map} that contains all the annotation attributes. + * Get an immutable {@link Map} that contains all the annotation attributes. *

The {@link Adapt adaptations} may be used to change the way that values are added. * @param adaptations adaptations that should be applied to the annotation values * @return an immutable map containing the attributes and values @@ -544,7 +547,7 @@ public interface MergedAnnotation { /** * Create a new {@link MergedAnnotation} instance of the specified - * annotation type with attributes values supplied by a map. + * annotation type with attribute values supplied by a map. * @param annotationType the annotation type * @param attributes the annotation attributes or {@code null} if just default * values should be used @@ -559,7 +562,7 @@ public interface MergedAnnotation { /** * Create a new {@link MergedAnnotation} instance of the specified - * annotation type with attributes values supplied by a map. + * annotation type with attribute values supplied by a map. * @param source the source for the annotation. This source is used only for * information and logging. It does not need to actually contain * the specified annotations and it will not be searched. @@ -576,7 +579,7 @@ public interface MergedAnnotation { /** * Create a new {@link MergedAnnotation} instance of the specified - * annotation type with attributes values supplied by a map. + * annotation type with attribute values supplied by a map. * @param classLoader the class loader used to resolve class attributes * @param source the source for the annotation. This source is used only for * information and logging. It does not need to actually contain @@ -595,7 +598,7 @@ public interface MergedAnnotation { /** - * Adaptations that can be applied to attributes values when creating + * Adaptations that can be applied to attribute values when creating * {@linkplain MergedAnnotation#asMap(Adapt...) Maps} or * {@link MergedAnnotation#asAnnotationAttributes(Adapt...) AnnotationAttributes}. */