Interface MergedAnnotations

All Superinterfaces:
Iterable<MergedAnnotation<Annotation>>

public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>>
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, the following code uses MergedAnnotations.SearchStrategy.TYPE_HIERARCHY to search for annotations on MyClass as well as in superclasses and implemented interfaces.

 MergedAnnotations mergedAnnotations =
     MergedAnnotations.search(TYPE_HIERARCHY).from(MyClass.class);
 

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.

Since:
5.2
Author:
Phillip Webb, Sam Brannen
See Also:
  • Method Details

    • isPresent

      <A extends Annotation> boolean isPresent(Class<A> annotationType)
      Determine if the specified annotation type is either directly present or meta-present.

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

      Parameters:
      annotationType - the annotation type to check
      Returns:
      true if the annotation is present
    • isPresent

      boolean isPresent(String annotationType)
      Determine if the specified annotation type is either directly present or meta-present.

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

      Parameters:
      annotationType - the fully qualified class name of the annotation type to check
      Returns:
      true if the annotation is present
    • isDirectlyPresent

      <A extends Annotation> boolean isDirectlyPresent(Class<A> annotationType)
      Determine if the specified annotation type is directly present.

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

      Parameters:
      annotationType - the annotation type to check
      Returns:
      true if the annotation is directly present
    • isDirectlyPresent

      boolean isDirectlyPresent(String annotationType)
      Determine if the specified annotation type is directly present.

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

      Parameters:
      annotationType - the fully qualified class name of the annotation type to check
      Returns:
      true if the annotation is directly present
    • get

      <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.
      Parameters:
      annotationType - the annotation type to get
      Returns:
      a MergedAnnotation instance
    • get

      <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate)
      Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
      Parameters:
      annotationType - the annotation type to get
      predicate - a predicate that must match, or null if only type matching is required
      Returns:
      a MergedAnnotation instance
      See Also:
    • get

      <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector)
      Get a matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
      Parameters:
      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
      Returns:
      a MergedAnnotation instance
      See Also:
    • get

      <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.
      Parameters:
      annotationType - the fully qualified class name of the annotation type to get
      Returns:
      a MergedAnnotation instance
    • get

      <A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate)
      Get the nearest matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
      Parameters:
      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
      Returns:
      a MergedAnnotation instance
      See Also:
    • get

      <A extends Annotation> MergedAnnotation<A> get(String annotationType, @Nullable Predicate<? super MergedAnnotation<A>> predicate, @Nullable MergedAnnotationSelector<A> selector)
      Get a matching annotation or meta-annotation of the specified type, or MergedAnnotation.missing() if none is present.
      Parameters:
      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
      Returns:
      a MergedAnnotation instance
      See Also:
    • stream

      <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().

      Parameters:
      annotationType - the annotation type to match
      Returns:
      a stream of matching annotations
    • stream

      <A extends Annotation> Stream<MergedAnnotation<A>> stream(String annotationType)
      Stream all annotations and meta-annotations that match the specified type.

      The resulting stream follows the same ordering rules as stream().

      Parameters:
      annotationType - the fully qualified class name of the annotation type to match
      Returns:
      a stream of matching annotations
    • stream

      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
    • from

      static MergedAnnotations from(AnnotatedElement element)
      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 MergedAnnotations.SearchStrategy.

      Parameters:
      element - the source element
      Returns:
      a MergedAnnotations instance containing the element's annotations
      See Also:
    • from

      Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the MergedAnnotations.SearchStrategy, related inherited elements.
      Parameters:
      element - the source element
      searchStrategy - the search strategy to use
      Returns:
      a MergedAnnotations instance containing the merged element annotations
      See Also:
    • from

      static MergedAnnotations from(AnnotatedElement element, MergedAnnotations.SearchStrategy searchStrategy, RepeatableContainers repeatableContainers)
      Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the MergedAnnotations.SearchStrategy, related inherited elements.
      Parameters:
      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
      See Also:
    • from

      static MergedAnnotations from(AnnotatedElement element, MergedAnnotations.SearchStrategy searchStrategy, RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter)
      Create a new MergedAnnotations instance containing all annotations and meta-annotations from the specified element and, depending on the MergedAnnotations.SearchStrategy, related inherited elements.
      Parameters:
      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
      See Also:
    • from

      static MergedAnnotations from(Annotation... annotations)
      Create a new MergedAnnotations instance from the specified annotations.
      Parameters:
      annotations - the annotations to include
      Returns:
      a MergedAnnotations instance containing the annotations
      See Also:
    • from

      static MergedAnnotations from(Object source, Annotation... annotations)
      Create a new MergedAnnotations instance from the specified annotations.
      Parameters:
      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
      Returns:
      a MergedAnnotations instance containing the annotations
      See Also:
    • from

      static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers)
      Create a new MergedAnnotations instance from the specified annotations.
      Parameters:
      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
    • from

      static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter)
      Create a new MergedAnnotations instance from the specified annotations.
      Parameters:
      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
    • of

      static MergedAnnotations of(Collection<MergedAnnotation<?>> annotations)
      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.

      Parameters:
      annotations - the annotations to include
      Returns:
      a MergedAnnotations instance containing the annotations
      See Also:
    • search

      Find merged annotations using the supplied MergedAnnotations.SearchStrategy and a fluent API for configuring and performing the search.

      See MergedAnnotations.Search for details.

      Parameters:
      searchStrategy - the search strategy to use
      Returns:
      a Search instance to perform the search
      Since:
      6.0