Browse Source

Polish MergedAnnotation internals

pull/23848/head
Sam Brannen 6 years ago
parent
commit
71400ea604
  1. 29
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java
  2. 4
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java
  3. 53
      spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java

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

@ -296,7 +296,7 @@ final class AnnotationTypeMapping { @@ -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 { @@ -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 { @@ -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}.
* <p>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 { @@ -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 { @@ -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<Method, Object, Object> 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;
}

4
spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java

@ -205,9 +205,9 @@ final class AnnotationTypeMappings { @@ -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<? extends Annotation> annotationType) {
return this.mappings.computeIfAbsent(annotationType, this::createMappings);

53
spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotation.java

@ -83,26 +83,28 @@ public interface MergedAnnotation<A extends Annotation> { @@ -83,26 +83,28 @@ public interface MergedAnnotation<A extends Annotation> {
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.
* <p>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.
* <p>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.
* <p>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<A extends Annotation> { @@ -111,7 +113,7 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* Get the index of the aggregate collection containing this annotation.
* Can be used to reorder a stream of annotations, for example, to give a
* <p>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<A extends Annotation> { @@ -122,11 +124,12 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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.
* <p>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<A extends Annotation> { @@ -136,8 +139,8 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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}.
* <p>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<A extends Annotation> { @@ -154,9 +157,9 @@ public interface MergedAnnotation<A extends Annotation> {
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}.
* <p>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<A extends Annotation> { @@ -458,7 +461,7 @@ public interface MergedAnnotation<A extends Annotation> {
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.
* <p>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<A extends Annotation> { @@ -544,7 +547,7 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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<A extends Annotation> { @@ -559,7 +562,7 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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 <em>actually</em> contain
* the specified annotations and it will not be searched.
@ -576,7 +579,7 @@ public interface MergedAnnotation<A extends Annotation> { @@ -576,7 +579,7 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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 <em>actually</em> contain
@ -595,7 +598,7 @@ public interface MergedAnnotation<A extends Annotation> { @@ -595,7 +598,7 @@ public interface MergedAnnotation<A extends Annotation> {
/**
* 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}.
*/

Loading…
Cancel
Save