Class TestContextAnnotationUtils

java.lang.Object
org.springframework.test.context.TestContextAnnotationUtils

public abstract class TestContextAnnotationUtils extends Object
TestContextAnnotationUtils is a collection of utility methods that complements the standard support already available in AnnotationUtils and AnnotatedElementUtils, while transparently honoring @NestedTestConfiguration semantics.

Mainly for internal use within the Spring TestContext Framework but also supported for third-party integrations with the TestContext framework.

Whereas AnnotationUtils and AnnotatedElementUtils provide utilities for getting or finding annotations, TestContextAnnotationUtils goes a step further by providing support for determining the root class on which an annotation is declared, either directly or indirectly via a composed annotation. This additional information is encapsulated in an TestContextAnnotationUtils.AnnotationDescriptor.

The additional information provided by an AnnotationDescriptor is required by the Spring TestContext Framework in order to be able to support class inheritance and enclosing class hierarchy traversals for annotations such as @ContextConfiguration, @TestExecutionListeners, and @ActiveProfiles which offer support for merging and overriding various inherited annotation attributes — for example, ContextConfiguration.inheritLocations().

Since:
5.3, though originally since 4.0 as org.springframework.test.util.MetaAnnotationUtils
Author:
Sam Brannen
See Also:
  • Constructor Details

    • TestContextAnnotationUtils

      public TestContextAnnotationUtils()
  • Method Details

    • hasAnnotation

      public static boolean hasAnnotation(Class<?> clazz, Class<? extends Annotation> annotationType)
      Determine if an annotation of the specified annotationType is present or meta-present on the supplied Class according to the search algorithm used in findMergedAnnotation(Class, Class).

      If this method returns true, then findMergedAnnotation(...) will return a non-null value.

      Parameters:
      clazz - the class to look for annotations on
      annotationType - the type of annotation to look for
      Returns:
      true if a matching annotation is present
      Since:
      5.3.3
      See Also:
    • findMergedAnnotation

      @Nullable public static <T extends Annotation> T findMergedAnnotation(Class<?> clazz, Class<T> annotationType)
      Find the first annotation of the specified annotationType within the annotation hierarchy above the supplied class, merge that annotation's attributes with matching attributes from annotations in lower levels of the annotation hierarchy, and synthesize the result back into an annotation of the specified annotationType.

      In the context of this method, the term "above" means within the superclass hierarchy or within the enclosing class hierarchy of the supplied class. The enclosing class hierarchy will only be searched according to @NestedTestConfiguration semantics.

      @AliasFor semantics are fully supported, both within a single annotation and within annotation hierarchies.

      Parameters:
      clazz - the class to look for annotations on
      annotationType - the type of annotation to look for
      Returns:
      the merged, synthesized Annotation, or null if not found
      See Also:
    • getMergedRepeatableAnnotations

      public static <T extends Annotation> Set<T> getMergedRepeatableAnnotations(Class<?> clazz, Class<T> annotationType)
      Get all repeatable annotations of the specified annotationType within the annotation hierarchy above the supplied class; and for each annotation found, merge that annotation's attributes with matching attributes from annotations in lower levels of the annotation hierarchy and synthesize the results back into an annotation of the specified annotationType.

      This method will find @Inherited annotations declared on superclasses if the supplied class does not have any local declarations of the repeatable annotation. If no inherited annotations are found, this method will search within the enclosing class hierarchy of the supplied class. The enclosing class hierarchy will only be searched according to @NestedTestConfiguration semantics.

      The container type that holds the repeatable annotations will be looked up via Repeatable.

      @AliasFor semantics are fully supported, both within a single annotation and within annotation hierarchies.

      Parameters:
      clazz - the class on which to search for annotations (never null)
      annotationType - the annotation type to find (never null)
      Returns:
      the set of all merged repeatable annotations found, or an empty set if none were found
      See Also:
    • findAnnotationDescriptor

      @Nullable public static <T extends Annotation> TestContextAnnotationUtils.AnnotationDescriptor<T> findAnnotationDescriptor(Class<?> clazz, Class<T> annotationType)
      Find the TestContextAnnotationUtils.AnnotationDescriptor for the supplied annotationType on the supplied Class, traversing its annotations, interfaces, superclasses, and enclosing classes if no annotation can be found on the given class itself.

      This method explicitly handles class-level annotations which are not declared as inherited as well as meta-annotations.

      The algorithm operates as follows:

      1. Search for the annotation on the given class and return a corresponding AnnotationDescriptor if found.
      2. Recursively search through all annotations that the given class declares.
      3. Recursively search through all interfaces implemented by the given class.
      4. Recursively search through the superclass hierarchy of the given class.
      5. Recursively search through the enclosing class hierarchy of the given class if appropriate according to @NestedTestConfiguration semantics.

      In this context, the term recursively means that the search process continues by returning to step #1 with the current annotation, interface, superclass, or enclosing class as the class to look for annotations on.

      Parameters:
      clazz - the class to look for annotations on
      annotationType - the type of annotation to look for
      Returns:
      the corresponding annotation descriptor if the annotation was found; otherwise null
      See Also:
    • findAnnotationDescriptorForTypes

      @Nullable public static TestContextAnnotationUtils.UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class<?> clazz, Class<? extends Annotation>... annotationTypes)
      Find the TestContextAnnotationUtils.UntypedAnnotationDescriptor for the first Class in the inheritance hierarchy of the specified clazz (including the specified clazz itself) which declares at least one of the specified annotationTypes.

      This method traverses the annotations, interfaces, superclasses, and enclosing classes of the specified clazz if no annotation can be found on the given class itself.

      This method explicitly handles class-level annotations which are not declared as inherited as well as meta-annotations.

      The algorithm operates as follows:

      1. Search for a local declaration of one of the annotation types on the given class and return a corresponding UntypedAnnotationDescriptor if found.
      2. Recursively search through all annotations that the given class declares.
      3. Recursively search through all interfaces implemented by the given class.
      4. Recursively search through the superclass hierarchy of the given class.
      5. Recursively search through the enclosing class hierarchy of the given class if appropriate according to @NestedTestConfiguration semantics.

      In this context, the term recursively means that the search process continues by returning to step #1 with the current annotation, interface, superclass, or enclosing class as the class to look for annotations on.

      Parameters:
      clazz - the class to look for annotations on
      annotationTypes - the types of annotations to look for
      Returns:
      the corresponding annotation descriptor if one of the annotations was found; otherwise null
      See Also:
    • searchEnclosingClass

      public static boolean searchEnclosingClass(Class<?> clazz)
      Determine if annotations on the enclosing class of the supplied class should be searched by annotation search algorithms within the Spring TestContext Framework.
      Parameters:
      clazz - the class whose enclosing class should potentially be searched
      Returns:
      true if the supplied class is an inner class whose enclosing class should be searched
      See Also: