/*
 * Copyright 2002-2020 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.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

Provides access to a collection of merged annotations, usually obtained from a source such as a Class or Method.

Each merged annotation represents a view where the attribute values may be "merged" from different source values, typically:

  • Explicit and Implicit @AliasFor declarations on one or more attributes within the annotation
  • Explicit @AliasFor declarations for a meta-annotation
  • Convention based attribute aliases for a meta-annotation
  • From a meta-annotation declaration

For example, a @PostMapping annotation might be defined as follows:

@Retention(RetentionPolicy.RUNTIME)
@RequestMapping(method = RequestMethod.POST)
public @interface PostMapping {
    @AliasFor(attribute = "path")
    String[] value() default {};
    @AliasFor(attribute = "value")
    String[] path() default {};
}

If a method is annotated with @PostMapping("/home") it will contain merged annotations for both @PostMapping and the meta-annotation @RequestMapping. The merged view of the @RequestMapping annotation will contain the following attributes:

Name Value Source
value "/home" Declared in @PostMapping
path "/home" Explicit @AliasFor
method RequestMethod.POST Declared in meta-annotation

MergedAnnotations can be obtained from any Java AnnotatedElement. They may also be used for sources that don't use reflection (such as those that directly parse bytecode).

Different search strategies can be used to locate related source elements that contain the annotations to be aggregated. For example, SearchStrategy.TYPE_HIERARCHY will search both superclasses and implemented interfaces.

From a MergedAnnotations instance you can either get a single annotation, or stream all annotations or just those that match a specific type. You can also quickly tell if an annotation is present.

Here are some typical examples:

// is an annotation present or meta-present?
mergedAnnotations.isPresent(ExampleAnnotation.class);
// get the merged "value" attribute of ExampleAnnotation (either directly or
// meta-present)
mergedAnnotations.get(ExampleAnnotation.class).getString("value");
// get all meta-annotations but no directly present annotations
mergedAnnotations.stream().filter(MergedAnnotation::isMetaPresent);
// get all ExampleAnnotation declarations (including any meta-annotations) and
// print the merged "value" attributes
mergedAnnotations.stream(ExampleAnnotation.class)
    .map(mergedAnnotation -> mergedAnnotation.getString("value"))
    .forEach(System.out::println);

NOTE: The MergedAnnotations API and its underlying model have been designed for composable annotations in Spring's common component model, with a focus on attribute aliasing and meta-annotation relationships. There is no support for retrieving plain Java annotations with this API; please use standard Java reflection or Spring's AnnotationUtils for simple annotation retrieval purposes.

Author:Phillip Webb, Sam Brannen
See Also:
Since:5.2
/** * Provides access to a collection of merged annotations, usually obtained * from a source such as a {@link Class} or {@link Method}. * * <p>Each merged annotation represents a view where the attribute values may be * "merged" from different source values, typically: * * <ul> * <li>Explicit and Implicit {@link AliasFor @AliasFor} declarations on one or * more attributes within the annotation</li> * <li>Explicit {@link AliasFor @AliasFor} declarations for a meta-annotation</li> * <li>Convention based attribute aliases for a meta-annotation</li> * <li>From a meta-annotation declaration</li> * </ul> * * <p>For example, a {@code @PostMapping} annotation might be defined as follows: * * <pre class="code"> * &#064;Retention(RetentionPolicy.RUNTIME) * &#064;RequestMapping(method = RequestMethod.POST) * public &#064;interface PostMapping { * * &#064;AliasFor(attribute = "path") * String[] value() default {}; * * &#064;AliasFor(attribute = "value") * String[] path() default {}; * } * </pre> * * <p>If a method is annotated with {@code @PostMapping("/home")} it will contain * merged annotations for both {@code @PostMapping} and the meta-annotation * {@code @RequestMapping}. The merged view of the {@code @RequestMapping} * annotation will contain the following attributes: * * <p><table border="1"> * <tr> * <th>Name</th> * <th>Value</th> * <th>Source</th> * </tr> * <tr> * <td>value</td> * <td>"/home"</td> * <td>Declared in {@code @PostMapping}</td> * </tr> * <tr> * <td>path</td> * <td>"/home"</td> * <td>Explicit {@code @AliasFor}</td> * </tr> * <tr> * <td>method</td> * <td>RequestMethod.POST</td> * <td>Declared in meta-annotation</td> * </tr> * </table> * * <p>{@link MergedAnnotations} can be obtained {@linkplain #from(AnnotatedElement) * from} any Java {@link AnnotatedElement}. They may also be used for sources that * don't use reflection (such as those that directly parse bytecode). * * <p>Different {@linkplain SearchStrategy search strategies} can be used to locate * related source elements that contain the annotations to be aggregated. For * example, {@link SearchStrategy#TYPE_HIERARCHY} will search both superclasses and * implemented interfaces. * * <p>From a {@link MergedAnnotations} instance you can either * {@linkplain #get(String) get} a single annotation, or {@linkplain #stream() * stream all annotations} or just those that match {@linkplain #stream(String) * a specific type}. You can also quickly tell if an annotation * {@linkplain #isPresent(String) is present}. * * <p>Here are some typical examples: * * <pre class="code"> * // is an annotation present or meta-present? * mergedAnnotations.isPresent(ExampleAnnotation.class); * * // get the merged "value" attribute of ExampleAnnotation (either directly or * // meta-present) * mergedAnnotations.get(ExampleAnnotation.class).getString("value"); * * // get all meta-annotations but no directly present annotations * mergedAnnotations.stream().filter(MergedAnnotation::isMetaPresent); * * // get all ExampleAnnotation declarations (including any meta-annotations) and * // print the merged "value" attributes * mergedAnnotations.stream(ExampleAnnotation.class) * .map(mergedAnnotation -&gt; mergedAnnotation.getString("value")) * .forEach(System.out::println); * </pre> * * <p><b>NOTE: The {@code MergedAnnotations} API and its underlying model have * been designed for composable annotations in Spring's common component model, * with a focus on attribute aliasing and meta-annotation relationships.</b> * There is no support for retrieving plain Java annotations with this API; * please use standard Java reflection or Spring's {@link AnnotationUtils} * for simple annotation retrieval purposes. * * @author Phillip Webb * @author Sam Brannen * @since 5.2 * @see MergedAnnotation * @see MergedAnnotationCollectors * @see MergedAnnotationPredicates * @see MergedAnnotationSelectors */
public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>> {
Determine if the specified annotation is either directly present or meta-present.

Equivalent to calling get(annotationType).isPresent().

Params:
  • annotationType – the annotation type to check
Returns:true if the annotation is present
/** * Determine if the specified annotation is either directly present or * meta-present. * <p>Equivalent to calling {@code get(annotationType).isPresent()}. * @param annotationType the annotation type to check * @return {@code true} if the annotation is present */
<A extends Annotation> boolean isPresent(Class<A> annotationType);
Determine if the specified annotation is either directly present or meta-present.

Equivalent to calling get(annotationType).isPresent().

Params:
  • annotationType – the fully qualified class name of the annotation type to check
Returns:true if the annotation is present
/** * Determine if the specified annotation is either directly present or * meta-present. * <p>Equivalent to calling {@code get(annotationType).isPresent()}. * @param annotationType the fully qualified class name of the annotation type * to check * @return {@code true} if the annotation is present */
boolean isPresent(String annotationType);
Determine if the specified annotation is directly present.

Equivalent to calling get(annotationType).isDirectlyPresent().

Params:
  • annotationType – the annotation type to check
Returns:true if the annotation is directly present
/** * Determine if the specified annotation is directly present. * <p>Equivalent to calling {@code get(annotationType).isDirectlyPresent()}. * @param annotationType the annotation type to check * @return {@code true} if the annotation is directly present */
<A extends Annotation> boolean isDirectlyPresent(Class<A> annotationType);
Determine if the specified annotation is directly present.

Equivalent to calling get(annotationType).isDirectlyPresent().

Params:
  • annotationType – the fully qualified class name of the annotation type to check
Returns:true if the annotation is directly present
/** * Determine if the specified annotation is directly present. * <p>Equivalent to calling {@code get(annotationType).isDirectlyPresent()}. * @param annotationType the fully qualified class name of the annotation type * to check * @return {@code true} if the annotation is directly present */
boolean isDirectlyPresent(String annotationType);
Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the annotation type to get
Returns:a MergedAnnotation instance
/** * Get the {@linkplain MergedAnnotationSelectors#nearest() nearest} matching * annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the annotation type to get * @return a {@link MergedAnnotation} instance */
<A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType);
Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the annotation type to get
  • predicate – a predicate that must match, or null if only type matching is required
See Also:
Returns:a MergedAnnotation instance
/** * Get the {@linkplain MergedAnnotationSelectors#nearest() nearest} matching * annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the annotation type to get * @param predicate a predicate that must match, or {@code null} if only * type matching is required * @return a {@link MergedAnnotation} instance * @see MergedAnnotationPredicates */
<A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate);
Get a matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the annotation type to get
  • predicate – a predicate that must match, or null if only type matching is required
  • selector – a selector used to choose the most appropriate annotation within an aggregate, or null to select the nearest
See Also:
Returns:a MergedAnnotation instance
/** * Get a matching annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the annotation type to get * @param predicate a predicate that must match, or {@code null} if only * type matching is required * @param selector a selector used to choose the most appropriate annotation * within an aggregate, or {@code null} to select the * {@linkplain MergedAnnotationSelectors#nearest() nearest} * @return a {@link MergedAnnotation} instance * @see MergedAnnotationPredicates * @see MergedAnnotationSelectors */
<A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector);
Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the fully qualified class name of the annotation type to get
Returns:a MergedAnnotation instance
/** * Get the {@linkplain MergedAnnotationSelectors#nearest() nearest} matching * annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the fully qualified class name of the annotation type * to get * @return a {@link MergedAnnotation} instance */
<A extends Annotation> MergedAnnotation<A> get(String annotationType);
Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the fully qualified class name of the annotation type to get
  • predicate – a predicate that must match, or null if only type matching is required
See Also:
Returns:a MergedAnnotation instance
/** * Get the {@linkplain MergedAnnotationSelectors#nearest() nearest} matching * annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the fully qualified class name of the annotation type * to get * @param predicate a predicate that must match, or {@code null} if only * type matching is required * @return a {@link MergedAnnotation} instance * @see MergedAnnotationPredicates */
<A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate);
Get a matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
Params:
  • annotationType – the fully qualified class name of the annotation type to get
  • predicate – a predicate that must match, or null if only type matching is required
  • selector – a selector used to choose the most appropriate annotation within an aggregate, or null to select the nearest
See Also:
Returns:a MergedAnnotation instance
/** * Get a matching annotation or meta-annotation of the specified type, or * {@link MergedAnnotation#missing()} if none is present. * @param annotationType the fully qualified class name of the annotation type * to get * @param predicate a predicate that must match, or {@code null} if only * type matching is required * @param selector a selector used to choose the most appropriate annotation * within an aggregate, or {@code null} to select the * {@linkplain MergedAnnotationSelectors#nearest() nearest} * @return a {@link MergedAnnotation} instance * @see MergedAnnotationPredicates * @see MergedAnnotationSelectors */
<A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector);
Stream all annotations and meta-annotations that match the specified type. The resulting stream follows the same ordering rules as stream().
Params:
  • annotationType – the annotation type to match
Returns:a stream of matching annotations
/** * Stream all annotations and meta-annotations that match the specified * type. The resulting stream follows the same ordering rules as * {@link #stream()}. * @param annotationType the annotation type to match * @return a stream of matching annotations */
<A extends Annotation> Stream<MergedAnnotation<A>> stream(Class<A> annotationType);
Stream all annotations and meta-annotations that match the specified type. The resulting stream follows the same ordering rules as stream().
Params:
  • annotationType – the fully qualified class name of the annotation type to match
Returns:a stream of matching annotations
/** * Stream all annotations and meta-annotations that match the specified * type. The resulting stream follows the same ordering rules as * {@link #stream()}. * @param annotationType the fully qualified class name of the annotation type * to match * @return a stream of matching annotations */
<A extends Annotation> Stream<MergedAnnotation<A>> stream(String annotationType);
Stream all annotations and meta-annotations contained in this collection. The resulting stream is ordered first by the aggregate index and then by the annotation distance (with the closest annotations first). This ordering means that, for most use-cases, the most suitable annotations appear earliest in the stream.
Returns:a stream of annotations
/** * Stream all annotations and meta-annotations contained in this collection. * The resulting stream is ordered first by the * {@linkplain MergedAnnotation#getAggregateIndex() aggregate index} and then * by the annotation distance (with the closest annotations first). This ordering * means that, for most use-cases, the most suitable annotations appear * earliest in the stream. * @return a stream of annotations */
Stream<MergedAnnotation<Annotation>> stream();
Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element. The resulting instance will not include any inherited annotations. If you want to include those as well you should use from(AnnotatedElement, SearchStrategy) with an appropriate SearchStrategy.
Params:
  • element – the source element
Returns:a MergedAnnotations instance containing the element's annotations
/** * Create a new {@link MergedAnnotations} instance containing all * annotations and meta-annotations from the specified element. The * resulting instance will not include any inherited annotations. If you * want to include those as well you should use * {@link #from(AnnotatedElement, SearchStrategy)} with an appropriate * {@link SearchStrategy}. * @param element the source element * @return a {@link MergedAnnotations} instance containing the element's * annotations */
static MergedAnnotations from(AnnotatedElement element) { return from(element, SearchStrategy.DIRECT); }
Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the SearchStrategy, related inherited elements.
Params:
  • element – the source element
  • searchStrategy – the search strategy to use
Returns:a MergedAnnotations instance containing the merged element annotations
/** * Create a new {@link MergedAnnotations} instance containing all * annotations and meta-annotations from the specified element and, * depending on the {@link SearchStrategy}, related inherited elements. * @param element the source element * @param searchStrategy the search strategy to use * @return a {@link MergedAnnotations} instance containing the merged * element annotations */
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy) { return from(element, searchStrategy, RepeatableContainers.standardRepeatables()); }
Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the SearchStrategy, related inherited elements.
Params:
  • element – the source element
  • searchStrategy – the search strategy to use
  • repeatableContainers – the repeatable containers that may be used by the element annotations or the meta-annotations
Returns:a MergedAnnotations instance containing the merged element annotations
/** * Create a new {@link MergedAnnotations} instance containing all * annotations and meta-annotations from the specified element and, * depending on the {@link SearchStrategy}, related inherited elements. * @param element the source element * @param searchStrategy the search strategy to use * @param repeatableContainers the repeatable containers that may be used by * the element annotations or the meta-annotations * @return a {@link MergedAnnotations} instance containing the merged * element annotations */
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy, RepeatableContainers repeatableContainers) { return from(element, searchStrategy, repeatableContainers, AnnotationFilter.PLAIN); }
Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the SearchStrategy, related inherited elements.
Params:
  • element – the source element
  • searchStrategy – the search strategy to use
  • repeatableContainers – the repeatable containers that may be used by the element annotations or the meta-annotations
  • annotationFilter – an annotation filter used to restrict the annotations considered
Returns:a MergedAnnotations instance containing the merged annotations for the supplied element
/** * Create a new {@link MergedAnnotations} instance containing all * annotations and meta-annotations from the specified element and, * depending on the {@link SearchStrategy}, related inherited elements. * @param element the source element * @param searchStrategy the search strategy to use * @param repeatableContainers the repeatable containers that may be used by * the element annotations or the meta-annotations * @param annotationFilter an annotation filter used to restrict the * annotations considered * @return a {@link MergedAnnotations} instance containing the merged * annotations for the supplied element */
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy, RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) { Assert.notNull(repeatableContainers, "RepeatableContainers must not be null"); Assert.notNull(annotationFilter, "AnnotationFilter must not be null"); return TypeMappedAnnotations.from(element, searchStrategy, repeatableContainers, annotationFilter); }
Create a new MergedAnnotations instance from the specified annotations.
Params:
  • annotations – the annotations to include
See Also:
Returns:a MergedAnnotations instance containing the annotations
/** * Create a new {@link MergedAnnotations} instance from the specified * annotations. * @param annotations the annotations to include * @return a {@link MergedAnnotations} instance containing the annotations * @see #from(Object, Annotation...) */
static MergedAnnotations from(Annotation... annotations) { return from(annotations, annotations); }
Create a new MergedAnnotations instance from the specified annotations.
Params:
  • source – the source for the annotations. 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.
  • annotations – the annotations to include
See Also:
Returns:a MergedAnnotations instance containing the annotations
/** * Create a new {@link MergedAnnotations} instance from the specified * annotations. * @param source the source for the annotations. 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. * @param annotations the annotations to include * @return a {@link MergedAnnotations} instance containing the annotations * @see #from(Annotation...) * @see #from(AnnotatedElement) */
static MergedAnnotations from(Object source, Annotation... annotations) { return from(source, annotations, RepeatableContainers.standardRepeatables()); }
Create a new MergedAnnotations instance from the specified annotations.
Params:
  • source – the source for the annotations. 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.
  • annotations – the annotations to include
  • repeatableContainers – the repeatable containers that may be used by meta-annotations
Returns:a MergedAnnotations instance containing the annotations
/** * Create a new {@link MergedAnnotations} instance from the specified * annotations. * @param source the source for the annotations. 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. * @param annotations the annotations to include * @param repeatableContainers the repeatable containers that may be used by * meta-annotations * @return a {@link MergedAnnotations} instance containing the annotations */
static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers) { return from(source, annotations, repeatableContainers, AnnotationFilter.PLAIN); }
Create a new MergedAnnotations instance from the specified annotations.
Params:
  • source – the source for the annotations. 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.
  • annotations – the annotations to include
  • repeatableContainers – the repeatable containers that may be used by meta-annotations
  • annotationFilter – an annotation filter used to restrict the annotations considered
Returns:a MergedAnnotations instance containing the annotations
/** * Create a new {@link MergedAnnotations} instance from the specified * annotations. * @param source the source for the annotations. 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. * @param annotations the annotations to include * @param repeatableContainers the repeatable containers that may be used by * meta-annotations * @param annotationFilter an annotation filter used to restrict the * annotations considered * @return a {@link MergedAnnotations} instance containing the annotations */
static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) { Assert.notNull(repeatableContainers, "RepeatableContainers must not be null"); Assert.notNull(annotationFilter, "AnnotationFilter must not be null"); return TypeMappedAnnotations.from(source, annotations, repeatableContainers, annotationFilter); }
Create a new MergedAnnotations instance from the specified collection of directly present annotations. This method allows a MergedAnnotations instance to be created from annotations that are not necessarily loaded using reflection. The provided annotations must all be directly present and must have an aggregate index of 0.

The resulting MergedAnnotations instance will contain both the specified annotations, and any meta-annotations that can be read using reflection.

Params:
  • annotations – the annotations to include
See Also:
Returns:a MergedAnnotations instance containing the annotations
/** * Create a new {@link MergedAnnotations} instance from the specified * collection of directly present annotations. This method allows a * {@link MergedAnnotations} instance to be created from annotations that * are not necessarily loaded using reflection. The provided annotations * must all be {@link MergedAnnotation#isDirectlyPresent() directly present} * and must have an {@link MergedAnnotation#getAggregateIndex() aggregate * index} of {@code 0}. * <p>The resulting {@link MergedAnnotations} instance will contain both the * specified annotations, and any meta-annotations that can be read using * reflection. * @param annotations the annotations to include * @return a {@link MergedAnnotations} instance containing the annotations * @see MergedAnnotation#of(ClassLoader, Object, Class, java.util.Map) */
static MergedAnnotations of(Collection<MergedAnnotation<?>> annotations) { return MergedAnnotationsCollection.of(annotations); }
Search strategies supported by MergedAnnotations.from(AnnotatedElement, SearchStrategy).

Each strategy creates a different set of aggregates that will be combined to create the final MergedAnnotations.

/** * Search strategies supported by * {@link MergedAnnotations#from(AnnotatedElement, SearchStrategy)}. * * <p>Each strategy creates a different set of aggregates that will be * combined to create the final {@link MergedAnnotations}. */
enum SearchStrategy {
Find only directly declared annotations, without considering @Inherited annotations and without searching superclasses or implemented interfaces.
/** * Find only directly declared annotations, without considering * {@link Inherited @Inherited} annotations and without searching * superclasses or implemented interfaces. */
DIRECT,
Find all directly declared annotations as well as any @Inherited superclass annotations. This strategy is only really useful when used with Class types since the @Inherited annotation is ignored for all other annotated elements. This strategy does not search implemented interfaces.
/** * Find all directly declared annotations as well as any * {@link Inherited @Inherited} superclass annotations. This strategy * is only really useful when used with {@link Class} types since the * {@link Inherited @Inherited} annotation is ignored for all other * {@linkplain AnnotatedElement annotated elements}. This strategy does * not search implemented interfaces. */
INHERITED_ANNOTATIONS,
Find all directly declared and superclass annotations. This strategy is similar to INHERITED_ANNOTATIONS except the annotations do not need to be meta-annotated with @Inherited. This strategy does not search implemented interfaces.
/** * Find all directly declared and superclass annotations. This strategy * is similar to {@link #INHERITED_ANNOTATIONS} except the annotations * do not need to be meta-annotated with {@link Inherited @Inherited}. * This strategy does not search implemented interfaces. */
SUPERCLASS,
Perform a full search of the entire type hierarchy, including superclasses and implemented interfaces. Superclass annotations do not need to be meta-annotated with @Inherited.
/** * Perform a full search of the entire type hierarchy, including * superclasses and implemented interfaces. Superclass annotations do * not need to be meta-annotated with {@link Inherited @Inherited}. */
TYPE_HIERARCHY,
Perform a full search of the entire type hierarchy on the source and any enclosing classes. This strategy is similar to TYPE_HIERARCHY except that enclosing classes are also searched. Superclass annotations do not need to be meta-annotated with @Inherited. When searching a Method source, this strategy is identical to TYPE_HIERARCHY.
/** * Perform a full search of the entire type hierarchy on the source * <em>and</em> any enclosing classes. This strategy is similar to * {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass() * enclosing classes} are also searched. Superclass annotations do not * need to be meta-annotated with {@link Inherited @Inherited}. When * searching a {@link Method} source, this strategy is identical to * {@link #TYPE_HIERARCHY}. */
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES } }