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.
|
||||
* <p>This method follows <em>get semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; 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
|
||||
* set if none were found
|
||||
* @param element the annotated element (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 set if none were found
|
||||
* @since 4.3
|
||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #getAllAnnotationAttributes(AnnotatedElement, String)
|
||||
|
@ -460,10 +460,10 @@ public class AnnotatedElementUtils {
|
|||
* single annotation and within annotation hierarchies.
|
||||
* <p>This method follows <em>get semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; 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
|
||||
* set if none were found
|
||||
* @param element the annotated element (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 set if none were found
|
||||
* @since 4.3
|
||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||
|
@ -488,13 +488,13 @@ public class AnnotatedElementUtils {
|
|||
* single annotation and within annotation hierarchies.
|
||||
* <p>This method follows <em>get semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; never {@code null}
|
||||
* @param annotationType the annotation type to find; never {@code null}
|
||||
* @param element the annotated element (never {@code null})
|
||||
* @param annotationType the annotation type to find (never {@code null})
|
||||
* @param containerType the type of the container that holds the annotations;
|
||||
* may be {@code null} if the container type should be looked up via
|
||||
* {@link java.lang.annotation.Repeatable}
|
||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
||||
* set if none were found
|
||||
* @return the set of all merged repeatable {@code Annotations} found,
|
||||
* or an empty set if none were found
|
||||
* @since 4.3
|
||||
* @see #getMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||
|
@ -724,10 +724,10 @@ public class AnnotatedElementUtils {
|
|||
* single annotation and within annotation hierarchies.
|
||||
* <p>This method follows <em>find semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; 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
|
||||
* set if none were found
|
||||
* @param element the annotated element (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 set if none were found
|
||||
* @since 4.3
|
||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #getAllMergedAnnotations(AnnotatedElement, Class)
|
||||
|
@ -756,10 +756,10 @@ public class AnnotatedElementUtils {
|
|||
* single annotation and within annotation hierarchies.
|
||||
* <p>This method follows <em>find semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; 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
|
||||
* set if none were found
|
||||
* @param element the annotated element (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 set if none were found
|
||||
* @since 4.3
|
||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
||||
|
@ -784,13 +784,13 @@ public class AnnotatedElementUtils {
|
|||
* single annotation and within annotation hierarchies.
|
||||
* <p>This method follows <em>find semantics</em> as described in the
|
||||
* {@linkplain AnnotatedElementUtils class-level javadoc}.
|
||||
* @param element the annotated element; never {@code null}
|
||||
* @param annotationType the annotation type to find; never {@code null}
|
||||
* @param element the annotated element (never {@code null})
|
||||
* @param annotationType the annotation type to find (never {@code null})
|
||||
* @param containerType the type of the container that holds the annotations;
|
||||
* may be {@code null} if the container type should be looked up via
|
||||
* {@link java.lang.annotation.Repeatable}
|
||||
* @return the set of all merged repeatable {@code Annotations} found, or an empty
|
||||
* set if none were found
|
||||
* @return the set of all merged repeatable {@code Annotations} found,
|
||||
* or an empty set if none were found
|
||||
* @since 4.3
|
||||
* @see #findMergedAnnotation(AnnotatedElement, Class)
|
||||
* @see #findAllMergedAnnotations(AnnotatedElement, Class)
|
||||
|
@ -947,9 +947,10 @@ public class AnnotatedElementUtils {
|
|||
|
||||
// Search in annotations
|
||||
for (Annotation annotation : annotations) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
if (annotation.annotationType() == annotationType ||
|
||||
annotation.annotationType().getName().equals(annotationName) ||
|
||||
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||
if (currentAnnotationType == annotationType ||
|
||||
currentAnnotationType.getName().equals(annotationName) ||
|
||||
processor.alwaysProcesses()) {
|
||||
T result = processor.process(element, annotation, metaDepth);
|
||||
if (result != null) {
|
||||
|
@ -962,7 +963,7 @@ public class AnnotatedElementUtils {
|
|||
}
|
||||
}
|
||||
// Repeatable annotations in container?
|
||||
else if (annotation.annotationType() == containerType) {
|
||||
else if (currentAnnotationType == containerType) {
|
||||
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
||||
T result = processor.process(element, contained, metaDepth);
|
||||
if (result != null) {
|
||||
|
@ -977,8 +978,9 @@ public class AnnotatedElementUtils {
|
|||
|
||||
// Recursively search in meta-annotations
|
||||
for (Annotation annotation : annotations) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
T result = searchWithGetSemantics(annotation.annotationType(), annotationType,
|
||||
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||
T result = searchWithGetSemantics(currentAnnotationType, annotationType,
|
||||
annotationName, containerType, processor, visited, metaDepth + 1);
|
||||
if (result != null) {
|
||||
processor.postProcess(element, annotation, result);
|
||||
|
@ -1051,7 +1053,7 @@ public class AnnotatedElementUtils {
|
|||
* have already been <em>visited</em>.
|
||||
* <p>The {@code metaDepth} parameter is explained in the
|
||||
* {@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 annotationName the fully qualified class name of the annotation
|
||||
* type to find (as an alternative to {@code annotationType})
|
||||
|
@ -1077,11 +1079,11 @@ public class AnnotatedElementUtils {
|
|||
|
||||
// Search in local annotations
|
||||
for (Annotation annotation : annotations) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
if (annotation.annotationType() == annotationType
|
||||
|| annotation.annotationType().getName().equals(annotationName)
|
||||
|| processor.alwaysProcesses()) {
|
||||
|
||||
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||
if (currentAnnotationType == annotationType ||
|
||||
currentAnnotationType.getName().equals(annotationName) ||
|
||||
processor.alwaysProcesses()) {
|
||||
T result = processor.process(element, annotation, metaDepth);
|
||||
if (result != null) {
|
||||
if (processor.aggregates() && metaDepth == 0) {
|
||||
|
@ -1093,7 +1095,7 @@ public class AnnotatedElementUtils {
|
|||
}
|
||||
}
|
||||
// Repeatable annotations in container?
|
||||
else if (annotation.annotationType() == containerType) {
|
||||
else if (currentAnnotationType == containerType) {
|
||||
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
|
||||
T result = processor.process(element, contained, metaDepth);
|
||||
if (result != null) {
|
||||
|
@ -1108,11 +1110,12 @@ public class AnnotatedElementUtils {
|
|||
|
||||
// Search in meta annotations on local annotations
|
||||
for (Annotation annotation : annotations) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
T result = searchWithFindSemantics(annotation.annotationType(), annotationType, annotationName,
|
||||
Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||
T result = searchWithFindSemantics(currentAnnotationType, annotationType, annotationName,
|
||||
containerType, processor, visited, metaDepth + 1);
|
||||
if (result != null) {
|
||||
processor.postProcess(annotation.annotationType(), annotation, result);
|
||||
processor.postProcess(currentAnnotationType, annotation, result);
|
||||
if (processor.aggregates() && metaDepth == 0) {
|
||||
aggregatedResults.add(result);
|
||||
}
|
||||
|
@ -1252,7 +1255,7 @@ public class AnnotatedElementUtils {
|
|||
* Resolve the container type for the supplied repeatable {@code annotationType}.
|
||||
* <p>Delegates to {@link AnnotationUtils#resolveContainerAnnotationType(Class)}.
|
||||
* @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
|
||||
* @since 4.3
|
||||
*/
|
||||
|
@ -1403,8 +1406,8 @@ public class AnnotatedElementUtils {
|
|||
* responsible for asking this processor if it {@link #aggregates} results
|
||||
* and then adding the post-processed results to the list returned by this
|
||||
* method.
|
||||
* @return the list of results aggregated by this processor; never
|
||||
* {@code null} unless {@link #aggregates} returns {@code false}
|
||||
* @return the list of results aggregated by this processor
|
||||
* (never {@code null} unless {@link #aggregates} returns {@code false})
|
||||
* @see #aggregates
|
||||
* @since 4.3
|
||||
*/
|
||||
|
|
|
@ -64,7 +64,7 @@ import org.springframework.util.StringUtils;
|
|||
* <h3>Terminology</h3>
|
||||
* The terms <em>directly present</em>, <em>indirectly present</em>, and
|
||||
* <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
|
||||
* is declared as a meta-annotation on some other annotation which is
|
||||
|
@ -492,9 +492,10 @@ public abstract class AnnotationUtils {
|
|||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
for (Annotation ann : annotatedElement.getDeclaredAnnotations()) {
|
||||
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
|
||||
annotation = findAnnotation((AnnotatedElement) ann.annotationType(), annotationType, visited);
|
||||
for (Annotation declaredAnn : annotatedElement.getDeclaredAnnotations()) {
|
||||
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
|
||||
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
|
||||
annotation = findAnnotation((AnnotatedElement) declaredType, annotationType, visited);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
|
@ -679,9 +680,10 @@ public abstract class AnnotationUtils {
|
|||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
for (Annotation ann : clazz.getDeclaredAnnotations()) {
|
||||
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
|
||||
annotation = findAnnotation(ann.annotationType(), annotationType, visited);
|
||||
for (Annotation declaredAnn : clazz.getDeclaredAnnotations()) {
|
||||
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
|
||||
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
|
||||
annotation = findAnnotation(declaredType, annotationType, visited);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
|
@ -816,7 +818,7 @@ public abstract class AnnotationUtils {
|
|||
* <p>If the supplied {@code clazz} is an interface, only the interface
|
||||
* itself will be checked. In accordance with standard meta-annotation
|
||||
* 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
|
||||
* annotation inheritance.
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* @since 4.2
|
||||
*/
|
||||
|
@ -1519,8 +1532,8 @@ public abstract class AnnotationUtils {
|
|||
* {@linkplain #synthesizeAnnotation(Map, Class, AnnotatedElement)
|
||||
* synthesized} versions of the maps from the input array.
|
||||
* @param maps the array of maps of annotation attributes to synthesize
|
||||
* @param annotationType the type of annotations to synthesize; never
|
||||
* {@code null}
|
||||
* @param annotationType the type of annotations to synthesize
|
||||
* (never {@code null})
|
||||
* @return a new array of synthesized annotations, or {@code null} if
|
||||
* the supplied array is {@code null}
|
||||
* @throws AnnotationConfigurationException if invalid configuration of
|
||||
|
@ -1668,8 +1681,8 @@ public abstract class AnnotationUtils {
|
|||
/**
|
||||
* Get the name of the overridden attribute configured via
|
||||
* {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}.
|
||||
* @param attribute the attribute from which to retrieve the override;
|
||||
* never {@code null}
|
||||
* @param attribute the attribute from which to retrieve the override
|
||||
* (never {@code null})
|
||||
* @param metaAnnotationType the type of meta-annotation in which the
|
||||
* overridden attribute is allowed to be declared
|
||||
* @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>.
|
||||
* <p>All methods in the returned list will be
|
||||
* {@linkplain ReflectionUtils#makeAccessible(Method) made accessible}.
|
||||
* @param annotationType the type in which to search for attribute methods;
|
||||
* never {@code null}
|
||||
* @param annotationType the type in which to search for attribute methods
|
||||
* (never {@code null})
|
||||
* @return all annotation attribute methods in the specified annotation
|
||||
* type (never {@code null}, though potentially <em>empty</em>)
|
||||
* @since 4.2
|
||||
|
@ -1906,7 +1919,7 @@ public abstract class AnnotationUtils {
|
|||
else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, currentAnnotationType)) {
|
||||
this.result.addAll(getValue(element, ann));
|
||||
}
|
||||
else if (!isInJavaLangAnnotationPackage(ann)) {
|
||||
else if (!isInJavaLangAnnotationPackage(currentAnnotationType)) {
|
||||
process(currentAnnotationType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,17 +92,18 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
|
|||
}
|
||||
|
||||
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 {
|
||||
// Only do attribute scanning for public annotations; we'd run into
|
||||
// IllegalAccessExceptions otherwise, and we don't want to mess with
|
||||
// accessibility in a SecurityManager environment.
|
||||
if (Modifier.isPublic(annotation.annotationType().getModifiers())) {
|
||||
String annotationName = annotation.annotationType().getName();
|
||||
if (Modifier.isPublic(annotationType.getModifiers())) {
|
||||
this.attributesMap.add(annotationName,
|
||||
AnnotationUtils.getAnnotationAttributes(annotation, false, true));
|
||||
}
|
||||
for (Annotation metaMetaAnnotation : annotation.annotationType().getAnnotations()) {
|
||||
for (Annotation metaMetaAnnotation : annotationType.getAnnotations()) {
|
||||
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");
|
||||
* 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)?
|
||||
for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) {
|
||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(
|
||||
composedAnnotation.annotationType(), visited, annotationType);
|
||||
for (Annotation composedAnn : clazz.getDeclaredAnnotations()) {
|
||||
Class<? extends Annotation> composedType = composedAnn.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) {
|
||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(composedType, visited, annotationType);
|
||||
if (descriptor != null) {
|
||||
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(
|
||||
composedAnnotation.annotationType(), visited, annotationTypes);
|
||||
if (descriptor != null) {
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation,
|
||||
descriptor.getAnnotation());
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||
composedAnnotation, descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +295,8 @@ public abstract class MetaAnnotationUtils {
|
|||
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||
Annotation composedAnnotation, T annotation) {
|
||||
|
||||
Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null");
|
||||
Assert.notNull(annotation, "annotation must not be null");
|
||||
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
||||
Assert.notNull(annotation, "Annotation must not be null");
|
||||
this.rootDeclaringClass = rootDeclaringClass;
|
||||
this.declaringClass = declaringClass;
|
||||
this.composedAnnotation = composedAnnotation;
|
||||
|
|
Loading…
Reference in New Issue