diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index b7e21147c9..22b6f13c8b 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -54,12 +54,20 @@ import org.springframework.util.StringUtils; * ({@link #getAnnotation(Method, Class)}) and a find lookup in the entire * inheritance hierarchy of the given method ({@link #findAnnotation(Method, Class)}). * + *
An annotation is meta-present on an element if the annotation + * is declared as a meta-annotation on some other annotation which is + * present on the element. + * *
Most {@code find*()} methods and some {@code get*()} methods in this class - * provide support for meta-annotations. Consult the Javadoc for each method in - * this class for details. For support for meta-annotations with - * attribute overrides in composed annotations, use - * {@link AnnotatedElementUtils} instead. + *
Most {@code find*()} methods and some {@code get*()} methods in this + * class provide support for finding annotations used as meta-annotations. + * Consult the Javadoc for each method in this class for details. For support + * for meta-annotations with attribute overrides in + * composed annotations, use {@link AnnotatedElementUtils} instead. * *
The search algorithms used by methods in this class stop searching for @@ -122,8 +130,8 @@ public abstract class AnnotationUtils { /** * Get a single {@link Annotation} of {@code annotationType} from the supplied - * {@link AnnotatedElement}, where the {@code AnnotatedElement} is either - * directly annotated or meta-annotated with the {@code annotationType}. + * {@link AnnotatedElement}, where the annotation is either present or + * meta-present on the {@code AnnotatedElement}. *
Note that this method supports only a single level of meta-annotations. * For support for arbitrary levels of meta-annotations, use * {@link #findAnnotation(AnnotatedElement, Class)} instead. @@ -154,8 +162,8 @@ public abstract class AnnotationUtils { /** * Get a single {@link Annotation} of {@code annotationType} from the - * supplied {@link Method}, where the method is either directly annotated - * or meta-annotated with the {@code annotationType}. + * supplied {@link Method}, where the annotation is either present + * or meta-present on the method. *
Correctly handles bridge {@link Method Methods} generated by the compiler. *
Note that this method supports only a single level of meta-annotations. * For support for arbitrary levels of meta-annotations, use @@ -216,15 +224,17 @@ public abstract class AnnotationUtils { } /** - * Get the possibly repeating {@link Annotation}s of {@code annotationType} - * from the supplied {@link Method}. - *
Deals with both a single direct annotation and repeating annotations - * nested within a containing annotation. + * Get the repeatable {@link Annotation}s of {@code annotationType} + * from the supplied {@link Method}, where such annotations are either + * present or meta-present on the method. + *
Handles both single annotations and annotations nested within a + * containing annotation. *
Correctly handles bridge {@link Method Methods} generated by the compiler. *
Meta-annotations will be searched if the annotation is not - * directly present on the supplied method. - * @param method the method to look for annotations on - * @param containerAnnotationType the class of the container that holds the annotations + * present on the supplied method. + * @param method the method to look for annotations on; never {@code null} + * @param containerAnnotationType the type of the container that holds the + * annotations; may be {@code null} if a container is not supported * @param annotationType the annotation type to look for * @return the annotations found or an empty set; never {@code null} * @since 4.0 @@ -239,14 +249,16 @@ public abstract class AnnotationUtils { } /** - * Get the possibly repeating {@link Annotation}s of {@code annotationType} from the - * supplied {@link AnnotatedElement}. - *
Deals with both a single direct annotation and repeating annotations - * nested within a containing annotation. + * Get the repeatable {@link Annotation}s of {@code annotationType} + * from the supplied {@link AnnotatedElement}, where such annotations are + * either present or meta-present on the element. + *
Handles both single annotations and annotations nested within a + * containing annotation. *
Meta-annotations will be searched if the annotation is not - * directly present on the supplied element. - * @param annotatedElement the element to look for annotations on - * @param containerAnnotationType the class of the container that holds the annotations + * present on the supplied element. + * @param annotatedElement the element to look for annotations on; never {@code null} + * @param containerAnnotationType the type of the container that holds the + * annotations; may be {@code null} if a container is not supported * @param annotationType the annotation type to look for * @return the annotations found or an empty set; never {@code null} * @since 4.0 @@ -328,7 +340,8 @@ public abstract class AnnotationUtils { /** * Find a single {@link Annotation} of {@code annotationType} on the supplied * {@link Method}, traversing its super methods (i.e., from superclasses and - * interfaces) if no annotation can be found on the given method itself. + * interfaces) if the annotation is not directly present on the given + * method itself. *
Correctly handles bridge {@link Method Methods} generated by the compiler. *
Meta-annotations will be searched if the annotation is not * directly present on the method. @@ -423,8 +436,8 @@ public abstract class AnnotationUtils { /** * Find a single {@link Annotation} of {@code annotationType} on the * supplied {@link Class}, traversing its interfaces, annotations, and - * superclasses if the annotation is not present on the given class - * itself. + * superclasses if the annotation is not directly present on + * the given class itself. *
This method explicitly handles class-level annotations which are not * declared as {@link java.lang.annotation.Inherited inherited} as well * as meta-annotations and annotations on interfaces. @@ -505,21 +518,22 @@ public abstract class AnnotationUtils { } /** - * Find the first {@link Class} in the inheritance hierarchy of the specified {@code clazz} - * (including the specified {@code clazz} itself) which declares an annotation for the - * specified {@code annotationType}, or {@code null} if not found. If the supplied - * {@code clazz} is {@code null}, {@code null} will be returned. - *
If the supplied {@code clazz} is an interface, only the interface itself will be checked; - * the inheritance hierarchy for interfaces will not be traversed. + * Find the first {@link Class} in the inheritance hierarchy of the + * specified {@code clazz} (including the specified {@code clazz} itself) + * on which an annotation of the specified {@code annotationType} is + * directly present. + *
If the supplied {@code clazz} is an interface, only the interface + * itself will be checked; the inheritance hierarchy for interfaces will + * not be traversed. *
Meta-annotations will not be searched. - *
The standard {@link Class} API does not provide a mechanism for determining which class - * in an inheritance hierarchy actually declares an {@link Annotation}, so we need to handle - * this explicitly. - * @param annotationType the annotation type to look for, both locally and as a meta-annotation - * @param clazz the class on which to check for the annotation (may be {@code null}) - * @return the first {@link Class} in the inheritance hierarchy of the specified {@code clazz} - * which declares an annotation of the specified {@code annotationType}, or {@code null} - * if not found + *
The standard {@link Class} API does not provide a mechanism for + * determining which class in an inheritance hierarchy actually declares + * an {@link Annotation}, so we need to handle this explicitly. + * @param annotationType the annotation type to look for + * @param clazz the class to check for the annotation on (may be {@code null}) + * @return the first {@link Class} in the inheritance hierarchy that + * declares an annotation of the specified {@code annotationType}, or + * {@code null} if not found * @see Class#isAnnotationPresent(Class) * @see Class#getDeclaredAnnotations() * @see #findAnnotationDeclaringClassForTypes(List, Class) @@ -537,25 +551,22 @@ public abstract class AnnotationUtils { } /** - * Find the first {@link Class} in the inheritance hierarchy of the specified - * {@code clazz} (including the specified {@code clazz} itself) which declares - * at least one of the specified {@code annotationTypes}, or {@code null} if - * none of the specified annotation types could be found. - *
If the supplied {@code clazz} is {@code null}, {@code null} will be - * returned. - *
If the supplied {@code clazz} is an interface, only the interface itself - * will be checked; the inheritance hierarchy for interfaces will not be traversed. + * Find the first {@link Class} in the inheritance hierarchy of the + * specified {@code clazz} (including the specified {@code clazz} itself) + * on which at least one of the specified {@code annotationTypes} is + * directly present. + *
If the supplied {@code clazz} is an interface, only the interface + * itself will be checked; the inheritance hierarchy for interfaces will + * not be traversed. *
Meta-annotations will not be searched. - *
The standard {@link Class} API does not provide a mechanism for determining - * which class in an inheritance hierarchy actually declares one of several - * candidate {@linkplain Annotation annotations}, so we need to handle this - * explicitly. - * @param annotationTypes the list of Class objects corresponding to the - * annotation types - * @param clazz the Class object corresponding to the class on which to check - * for the annotations, or {@code null} - * @return the first {@link Class} in the inheritance hierarchy of the specified - * {@code clazz} which declares an annotation of at least one of the specified + *
The standard {@link Class} API does not provide a mechanism for + * determining which class in an inheritance hierarchy actually declares + * one of several candidate {@linkplain Annotation annotations}, so we + * need to handle this explicitly. + * @param annotationTypes the annotation types to look for + * @param clazz the class to check for the annotations on, or {@code null} + * @return the first {@link Class} in the inheritance hierarchy that + * declares an annotation of at least one of the specified * {@code annotationTypes}, or {@code null} if not found * @since 3.2.2 * @see Class#isAnnotationPresent(Class) @@ -577,18 +588,19 @@ public abstract class AnnotationUtils { } /** - * Determine whether an annotation of the specified {@code annotationType} is - * declared locally (i.e., directly present) on the supplied - * {@code clazz}. The supplied {@link Class} may represent any type. + * Determine whether an annotation of the specified {@code annotationType} + * is declared locally (i.e., directly present) on the supplied + * {@code clazz}. + *
The supplied {@link Class} may represent any type. *
Meta-annotations will not be searched. - *
Note: This method does not determine if the annotation is - * {@linkplain java.lang.annotation.Inherited inherited}. For greater clarity - * regarding inherited annotations, consider using + *
Note: This method does not determine if the annotation + * is {@linkplain java.lang.annotation.Inherited inherited}. For greater + * clarity regarding inherited annotations, consider using * {@link #isAnnotationInherited(Class, Class)} instead. - * @param annotationType the Class object corresponding to the annotation type - * @param clazz the Class object corresponding to the class on which to check for the annotation + * @param annotationType the annotation type to look for + * @param clazz the class to check for the annotation on * @return {@code true} if an annotation of the specified {@code annotationType} - * is directly present on the supplied {@code clazz} + * is directly present * @see java.lang.Class#getDeclaredAnnotations() * @see java.lang.Class#getDeclaredAnnotation(Class) * @see #isAnnotationInherited(Class, Class) @@ -596,12 +608,10 @@ public abstract class AnnotationUtils { public static boolean isAnnotationDeclaredLocally(Class extends Annotation> annotationType, Class> clazz) { Assert.notNull(annotationType, "Annotation type must not be null"); Assert.notNull(clazz, "Class must not be null"); - boolean declaredLocally = false; try { for (Annotation ann : clazz.getDeclaredAnnotations()) { if (ann.annotationType().equals(annotationType)) { - declaredLocally = true; - break; + return true; } } } @@ -609,22 +619,25 @@ public abstract class AnnotationUtils { // Assuming nested Class values not resolvable within annotation attributes... logIntrospectionFailure(clazz, ex); } - return declaredLocally; + return false; } /** - * Determine whether an annotation of the specified {@code annotationType} is present - * on the supplied {@code clazz} and is {@linkplain java.lang.annotation.Inherited inherited} - * (i.e., not declared locally for the class). + * Determine whether an annotation of the specified {@code annotationType} + * is present on the supplied {@code clazz} and is + * {@linkplain java.lang.annotation.Inherited inherited} (i.e., not + * directly present). *
Meta-annotations will not be searched. - *
If the supplied {@code clazz} is an interface, only the interface itself will be checked. - * In accordance with standard meta-annotation semantics, the inheritance hierarchy for interfaces - * will not 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 Class object corresponding to the annotation type - * @param clazz the Class object corresponding to the class on which to check for the annotation - * @return {@code true} if an annotation of the specified {@code annotationType} is present - * on the supplied {@code clazz} and is inherited + *
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} + * for the {@code @Inherited} meta-annotation for further details regarding + * annotation inheritance. + * @param annotationType the annotation type to look for + * @param clazz the class to check for the annotation on + * @return {@code true} if an annotation of the specified {@code annotationType} + * is present and inherited * @see Class#isAnnotationPresent(Class) * @see #isAnnotationDeclaredLocally(Class, Class) */