Minimize reflective interaction with annotation instances during retrieval
Issue: SPR-15387
This commit is contained in:
parent
aa3573b2bc
commit
3037277d0e
|
@ -427,10 +427,10 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>get semantics</em> as described in the
|
* <p>This method follows <em>get semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @return the set of all merged, synthesized {@code Annotations} found, or an empty
|
* @return the set of all merged, synthesized {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #getAllAnnotationAttributes(AnnotatedElement, String)
|
* @see #getAllAnnotationAttributes(AnnotatedElement, String)
|
||||||
|
@ -460,10 +460,10 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>get semantics</em> as described in the
|
* <p>This method follows <em>get semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
* @return the set of all merged repeatable {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||||
|
@ -488,13 +488,13 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>get semantics</em> as described in the
|
* <p>This method follows <em>get semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @param containerType the type of the container that holds the annotations;
|
* @param containerType the type of the container that holds the annotations;
|
||||||
* may be {@code null} if the container type should be looked up via
|
* may be {@code null} if the container type should be looked up via
|
||||||
* {@link java.lang.annotation.Repeatable}
|
* {@link java.lang.annotation.Repeatable}
|
||||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
* @return the set of all merged repeatable {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||||
|
@ -724,10 +724,10 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>find semantics</em> as described in the
|
* <p>This method follows <em>find semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @return the set of all merged, synthesized {@code Annotations} found, or an empty
|
* @return the set of all merged, synthesized {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||||
|
@ -756,10 +756,10 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>find semantics</em> as described in the
|
* <p>This method follows <em>find semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
* @return the set of all merged repeatable {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
||||||
|
@ -784,13 +784,13 @@ public class AnnotatedElementUtils {
|
||||||
* single annotation and within annotation hierarchies.
|
* single annotation and within annotation hierarchies.
|
||||||
* <p>This method follows <em>find semantics</em> as described in the
|
* <p>This method follows <em>find semantics</em> as described in the
|
||||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find; never {@code null}
|
* @param annotationType the annotation type to find (never {@code null})
|
||||||
* @param containerType the type of the container that holds the annotations;
|
* @param containerType the type of the container that holds the annotations;
|
||||||
* may be {@code null} if the container type should be looked up via
|
* may be {@code null} if the container type should be looked up via
|
||||||
* {@link java.lang.annotation.Repeatable}
|
* {@link java.lang.annotation.Repeatable}
|
||||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
* @return the set of all merged repeatable {@code Annotations} found,
|
||||||
* set if none were found
|
* or an empty set if none were found
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||||
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
||||||
|
@ -947,9 +947,10 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Search in annotations
|
// Search in annotations
|
||||||
for (Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||||
if (annotation.annotationType() == annotationType ||
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||||
annotation.annotationType().getName().equals(annotationName) ||
|
if (currentAnnotationType == annotationType ||
|
||||||
|
currentAnnotationType.getName().equals(annotationName) ||
|
||||||
processor.alwaysProcesses()) {
|
processor.alwaysProcesses()) {
|
||||||
T result = processor.process(element, annotation, metaDepth);
|
T result = processor.process(element, annotation, metaDepth);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -962,7 +963,7 @@ public class AnnotatedElementUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Repeatable annotations in container?
|
// Repeatable annotations in container?
|
||||||
else if (annotation.annotationType() == containerType) {
|
else if (currentAnnotationType == containerType) {
|
||||||
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
||||||
T result = processor.process(element, contained, metaDepth);
|
T result = processor.process(element, contained, metaDepth);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -977,8 +978,9 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Recursively search in meta-annotations
|
// Recursively search in meta-annotations
|
||||||
for (Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||||
T result = searchWithGetSemantics(annotation.annotationType(), annotationType,
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||||
|
T result = searchWithGetSemantics(currentAnnotationType, annotationType,
|
||||||
annotationName, containerType, processor, visited, metaDepth + 1);
|
annotationName, containerType, processor, visited, metaDepth + 1);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
processor.postProcess(element, annotation, result);
|
processor.postProcess(element, annotation, result);
|
||||||
|
@ -1051,7 +1053,7 @@ public class AnnotatedElementUtils {
|
||||||
* have already been <em>visited</em>.
|
* have already been <em>visited</em>.
|
||||||
* <p>The {@code metaDepth} parameter is explained in the
|
* <p>The {@code metaDepth} parameter is explained in the
|
||||||
* {@link Processor#process process()} method of the {@link Processor} API.
|
* {@link Processor#process process()} method of the {@link Processor} API.
|
||||||
* @param element the annotated element; never {@code null}
|
* @param element the annotated element (never {@code null})
|
||||||
* @param annotationType the annotation type to find
|
* @param annotationType the annotation type to find
|
||||||
* @param annotationName the fully qualified class name of the annotation
|
* @param annotationName the fully qualified class name of the annotation
|
||||||
* type to find (as an alternative to {@code annotationType})
|
* type to find (as an alternative to {@code annotationType})
|
||||||
|
@ -1077,11 +1079,11 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Search in local annotations
|
// Search in local annotations
|
||||||
for (Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||||
if (annotation.annotationType() == annotationType
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||||
|| annotation.annotationType().getName().equals(annotationName)
|
if (currentAnnotationType == annotationType ||
|
||||||
|| processor.alwaysProcesses()) {
|
currentAnnotationType.getName().equals(annotationName) ||
|
||||||
|
processor.alwaysProcesses()) {
|
||||||
T result = processor.process(element, annotation, metaDepth);
|
T result = processor.process(element, annotation, metaDepth);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (processor.aggregates() && metaDepth == 0) {
|
if (processor.aggregates() && metaDepth == 0) {
|
||||||
|
@ -1093,7 +1095,7 @@ public class AnnotatedElementUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Repeatable annotations in container?
|
// Repeatable annotations in container?
|
||||||
else if (annotation.annotationType() == containerType) {
|
else if (currentAnnotationType == containerType) {
|
||||||
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
||||||
T result = processor.process(element, contained, metaDepth);
|
T result = processor.process(element, contained, metaDepth);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -1108,11 +1110,12 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Search in meta annotations on local annotations
|
// Search in meta annotations on local annotations
|
||||||
for (Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||||
T result = searchWithFindSemantics(annotation.annotationType(), annotationType, annotationName,
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||||
|
T result = searchWithFindSemantics(currentAnnotationType, annotationType, annotationName,
|
||||||
containerType, processor, visited, metaDepth + 1);
|
containerType, processor, visited, metaDepth + 1);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
processor.postProcess(annotation.annotationType(), annotation, result);
|
processor.postProcess(currentAnnotationType, annotation, result);
|
||||||
if (processor.aggregates() && metaDepth == 0) {
|
if (processor.aggregates() && metaDepth == 0) {
|
||||||
aggregatedResults.add(result);
|
aggregatedResults.add(result);
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1255,7 @@ public class AnnotatedElementUtils {
|
||||||
* Resolve the container type for the supplied repeatable {@code annotationType}.
|
* Resolve the container type for the supplied repeatable {@code annotationType}.
|
||||||
* <p>Delegates to {@link AnnotationUtils#resolveContainerAnnotationType(Class)}.
|
* <p>Delegates to {@link AnnotationUtils#resolveContainerAnnotationType(Class)}.
|
||||||
* @param annotationType the annotation type to resolve the container for
|
* @param annotationType the annotation type to resolve the container for
|
||||||
* @return the container type; never {@code null}
|
* @return the container type (never {@code null})
|
||||||
* @throws IllegalArgumentException if the container type cannot be resolved
|
* @throws IllegalArgumentException if the container type cannot be resolved
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
|
@ -1403,8 +1406,8 @@ public class AnnotatedElementUtils {
|
||||||
* responsible for asking this processor if it {@link #aggregates} results
|
* responsible for asking this processor if it {@link #aggregates} results
|
||||||
* and then adding the post-processed results to the list returned by this
|
* and then adding the post-processed results to the list returned by this
|
||||||
* method.
|
* method.
|
||||||
* @return the list of results aggregated by this processor; never
|
* @return the list of results aggregated by this processor
|
||||||
* {@code null} unless {@link #aggregates} returns {@code false}
|
* (never {@code null} unless {@link #aggregates} returns {@code false})
|
||||||
* @see #aggregates
|
* @see #aggregates
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -64,7 +64,7 @@ import org.springframework.util.StringUtils;
|
||||||
* <h3>Terminology</h3>
|
* <h3>Terminology</h3>
|
||||||
* The terms <em>directly present</em>, <em>indirectly present</em>, and
|
* The terms <em>directly present</em>, <em>indirectly present</em>, and
|
||||||
* <em>present</em> have the same meanings as defined in the class-level
|
* <em>present</em> have the same meanings as defined in the class-level
|
||||||
* Javadoc for {@link AnnotatedElement} (in Java 8).
|
* javadoc for {@link AnnotatedElement} (in Java 8).
|
||||||
*
|
*
|
||||||
* <p>An annotation is <em>meta-present</em> on an element if the annotation
|
* <p>An annotation is <em>meta-present</em> on an element if the annotation
|
||||||
* is declared as a meta-annotation on some other annotation which is
|
* is declared as a meta-annotation on some other annotation which is
|
||||||
|
@ -492,9 +492,10 @@ public abstract class AnnotationUtils {
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
for (Annotation ann : annotatedElement.getDeclaredAnnotations()) {
|
for (Annotation declaredAnn : annotatedElement.getDeclaredAnnotations()) {
|
||||||
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
|
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
|
||||||
annotation = findAnnotation((AnnotatedElement) ann.annotationType(), annotationType, visited);
|
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
|
||||||
|
annotation = findAnnotation((AnnotatedElement) declaredType, annotationType, visited);
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
@ -679,9 +680,10 @@ public abstract class AnnotationUtils {
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
for (Annotation ann : clazz.getDeclaredAnnotations()) {
|
for (Annotation declaredAnn : clazz.getDeclaredAnnotations()) {
|
||||||
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
|
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
|
||||||
annotation = findAnnotation(ann.annotationType(), annotationType, visited);
|
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
|
||||||
|
annotation = findAnnotation(declaredType, annotationType, visited);
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
@ -816,7 +818,7 @@ public abstract class AnnotationUtils {
|
||||||
* <p>If the supplied {@code clazz} is an interface, only the interface
|
* <p>If the supplied {@code clazz} is an interface, only the interface
|
||||||
* itself will be checked. In accordance with standard meta-annotation
|
* itself will be checked. In accordance with standard meta-annotation
|
||||||
* semantics in Java, the inheritance hierarchy for interfaces will not
|
* semantics in Java, the inheritance hierarchy for interfaces will not
|
||||||
* be traversed. See the {@linkplain java.lang.annotation.Inherited Javadoc}
|
* be traversed. See the {@linkplain java.lang.annotation.Inherited javadoc}
|
||||||
* for the {@code @Inherited} meta-annotation for further details regarding
|
* for the {@code @Inherited} meta-annotation for further details regarding
|
||||||
* annotation inheritance.
|
* annotation inheritance.
|
||||||
* @param annotationType the annotation type to look for
|
* @param annotationType the annotation type to look for
|
||||||
|
@ -868,13 +870,24 @@ public abstract class AnnotationUtils {
|
||||||
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
||||||
*/
|
*/
|
||||||
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
|
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
|
||||||
return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType().getName()));
|
return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the {@link Annotation} with the supplied name is defined
|
* Determine if the {@link Annotation} with the supplied name is defined
|
||||||
* in the core JDK {@code java.lang.annotation} package.
|
* in the core JDK {@code java.lang.annotation} package.
|
||||||
* @param annotationType the name of the annotation type to check (never {@code null} or empty)
|
* @param annotationType the annotation type to check
|
||||||
|
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
||||||
|
* @since 4.3.8
|
||||||
|
*/
|
||||||
|
static boolean isInJavaLangAnnotationPackage(Class<? extends Annotation> annotationType) {
|
||||||
|
return (annotationType != null && isInJavaLangAnnotationPackage(annotationType.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the {@link Annotation} with the supplied name is defined
|
||||||
|
* in the core JDK {@code java.lang.annotation} package.
|
||||||
|
* @param annotationType the name of the annotation type to check
|
||||||
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
|
@ -1519,8 +1532,8 @@ public abstract class AnnotationUtils {
|
||||||
* {@linkplain #synthesizeAnnotation(Map, Class, AnnotatedElement)
|
* {@linkplain #synthesizeAnnotation(Map, Class, AnnotatedElement)
|
||||||
* synthesized} versions of the maps from the input array.
|
* synthesized} versions of the maps from the input array.
|
||||||
* @param maps the array of maps of annotation attributes to synthesize
|
* @param maps the array of maps of annotation attributes to synthesize
|
||||||
* @param annotationType the type of annotations to synthesize; never
|
* @param annotationType the type of annotations to synthesize
|
||||||
* {@code null}
|
* (never {@code null})
|
||||||
* @return a new array of synthesized annotations, or {@code null} if
|
* @return a new array of synthesized annotations, or {@code null} if
|
||||||
* the supplied array is {@code null}
|
* the supplied array is {@code null}
|
||||||
* @throws AnnotationConfigurationException if invalid configuration of
|
* @throws AnnotationConfigurationException if invalid configuration of
|
||||||
|
@ -1668,8 +1681,8 @@ public abstract class AnnotationUtils {
|
||||||
/**
|
/**
|
||||||
* Get the name of the overridden attribute configured via
|
* Get the name of the overridden attribute configured via
|
||||||
* {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}.
|
* {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}.
|
||||||
* @param attribute the attribute from which to retrieve the override;
|
* @param attribute the attribute from which to retrieve the override
|
||||||
* never {@code null}
|
* (never {@code null})
|
||||||
* @param metaAnnotationType the type of meta-annotation in which the
|
* @param metaAnnotationType the type of meta-annotation in which the
|
||||||
* overridden attribute is allowed to be declared
|
* overridden attribute is allowed to be declared
|
||||||
* @return the name of the overridden attribute, or {@code null} if not
|
* @return the name of the overridden attribute, or {@code null} if not
|
||||||
|
@ -1696,8 +1709,8 @@ public abstract class AnnotationUtils {
|
||||||
* match Java's requirements for annotation <em>attributes</em>.
|
* match Java's requirements for annotation <em>attributes</em>.
|
||||||
* <p>All methods in the returned list will be
|
* <p>All methods in the returned list will be
|
||||||
* {@linkplain ReflectionUtils#makeAccessible(Method) made accessible}.
|
* {@linkplain ReflectionUtils#makeAccessible(Method) made accessible}.
|
||||||
* @param annotationType the type in which to search for attribute methods;
|
* @param annotationType the type in which to search for attribute methods
|
||||||
* never {@code null}
|
* (never {@code null})
|
||||||
* @return all annotation attribute methods in the specified annotation
|
* @return all annotation attribute methods in the specified annotation
|
||||||
* type (never {@code null}, though potentially <em>empty</em>)
|
* type (never {@code null}, though potentially <em>empty</em>)
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
|
@ -1906,7 +1919,7 @@ public abstract class AnnotationUtils {
|
||||||
else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, currentAnnotationType)) {
|
else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, currentAnnotationType)) {
|
||||||
this.result.addAll(getValue(element, ann));
|
this.result.addAll(getValue(element, ann));
|
||||||
}
|
}
|
||||||
else if (!isInJavaLangAnnotationPackage(ann)) {
|
else if (!isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||||
process(currentAnnotationType);
|
process(currentAnnotationType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,17 +92,18 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recursivelyCollectMetaAnnotations(Set<Annotation> visited, Annotation annotation) {
|
private void recursivelyCollectMetaAnnotations(Set<Annotation> visited, Annotation annotation) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) && visited.add(annotation)) {
|
Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||||
|
String annotationName = annotationType.getName();
|
||||||
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) {
|
||||||
try {
|
try {
|
||||||
// Only do attribute scanning for public annotations; we'd run into
|
// Only do attribute scanning for public annotations; we'd run into
|
||||||
// IllegalAccessExceptions otherwise, and we don't want to mess with
|
// IllegalAccessExceptions otherwise, and we don't want to mess with
|
||||||
// accessibility in a SecurityManager environment.
|
// accessibility in a SecurityManager environment.
|
||||||
if (Modifier.isPublic(annotation.annotationType().getModifiers())) {
|
if (Modifier.isPublic(annotationType.getModifiers())) {
|
||||||
String annotationName = annotation.annotationType().getName();
|
|
||||||
this.attributesMap.add(annotationName,
|
this.attributesMap.add(annotationName,
|
||||||
AnnotationUtils.getAnnotationAttributes(annotation, false, true));
|
AnnotationUtils.getAnnotationAttributes(annotation, false, true));
|
||||||
}
|
}
|
||||||
for (Annotation metaMetaAnnotation : annotation.annotationType().getAnnotations()) {
|
for (Annotation metaMetaAnnotation : annotationType.getAnnotations()) {
|
||||||
recursivelyCollectMetaAnnotations(visited, metaMetaAnnotation);
|
recursivelyCollectMetaAnnotations(visited, metaMetaAnnotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -110,13 +110,13 @@ public abstract class MetaAnnotationUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
||||||
for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) {
|
for (Annotation composedAnn : clazz.getDeclaredAnnotations()) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) {
|
Class<? extends Annotation> composedType = composedAnn.annotationType();
|
||||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) {
|
||||||
composedAnnotation.annotationType(), visited, annotationType);
|
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(composedType, visited, annotationType);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
return new AnnotationDescriptor<>(
|
return new AnnotationDescriptor<>(
|
||||||
clazz, descriptor.getDeclaringClass(), composedAnnotation, descriptor.getAnnotation());
|
clazz, descriptor.getDeclaringClass(), composedAnn, descriptor.getAnnotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,8 +203,8 @@ public abstract class MetaAnnotationUtils {
|
||||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||||
composedAnnotation.annotationType(), visited, annotationTypes);
|
composedAnnotation.annotationType(), visited, annotationTypes);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation,
|
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||||
descriptor.getAnnotation());
|
composedAnnotation, descriptor.getAnnotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, visited, annotationTypes);
|
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, visited, annotationTypes);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||||
descriptor.getComposedAnnotation(), descriptor.getAnnotation());
|
descriptor.getComposedAnnotation(), descriptor.getAnnotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,8 +295,8 @@ public abstract class MetaAnnotationUtils {
|
||||||
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||||
Annotation composedAnnotation, T annotation) {
|
Annotation composedAnnotation, T annotation) {
|
||||||
|
|
||||||
Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null");
|
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
||||||
Assert.notNull(annotation, "annotation must not be null");
|
Assert.notNull(annotation, "Annotation must not be null");
|
||||||
this.rootDeclaringClass = rootDeclaringClass;
|
this.rootDeclaringClass = rootDeclaringClass;
|
||||||
this.declaringClass = declaringClass;
|
this.declaringClass = declaringClass;
|
||||||
this.composedAnnotation = composedAnnotation;
|
this.composedAnnotation = composedAnnotation;
|
||||||
|
|
Loading…
Reference in New Issue