public abstract class AnnotationUtils
extends java.lang.Object
Note that most of the features of this class are not provided by the JDK's introspection facilities themselves.
As a general rule for runtime-retained annotations (e.g. for transaction
control, authorization, or service exposure), always use the lookup methods
on this class (e.g., findAnnotation(Method, Class)
,
getAnnotation(Method, Class)
, and getAnnotations(Method)
)
instead of the plain annotation lookup methods in the JDK. You can still
explicitly choose between a get lookup on the given class level only
(getAnnotation(Method, Class)
) and a find lookup in the entire
inheritance hierarchy of the given method (findAnnotation(Method, Class)
).
AnnotatedElement
(in Java 8).
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. Annotation A
is meta-present
on another annotation if A
is either directly present or
meta-present on the other annotation.
Most find*()
methods and some 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 fine-grained support for
meta-annotations with attribute overrides in composed annotations,
consider using AnnotatedElementUtils
's more specific methods instead.
All public methods in this class that return annotations, arrays of
annotations, or AnnotationAttributes
transparently support attribute
aliases configured via @AliasFor
. Consult the various
synthesizeAnnotation*(..)
methods for details.
The search algorithms used by methods in this class stop searching for an annotation once the first annotation of the specified type has been found. As a consequence, additional annotations of the specified type will be silently ignored.
AliasFor
,
AnnotationAttributes
,
AnnotatedElementUtils
,
BridgeMethodResolver
,
AnnotatedElement.getAnnotations()
,
AnnotatedElement.getAnnotation(Class)
,
AnnotatedElement.getDeclaredAnnotations()
Modifier and Type | Class and Description |
---|---|
private static class |
AnnotationUtils.AliasDescriptor
AliasDescriptor encapsulates the declaration of @AliasFor
on a given annotation attribute and includes support for validating
the configuration of aliases (both explicit and implicit). |
private static class |
AnnotationUtils.AnnotationCacheKey
Cache key for the AnnotatedElement cache.
|
private static class |
AnnotationUtils.AnnotationCollector<A extends java.lang.annotation.Annotation> |
private static class |
AnnotationUtils.DefaultValueHolder |
Modifier and Type | Field and Description |
---|---|
private static java.util.Map<java.lang.reflect.Method,AnnotationUtils.AliasDescriptor> |
aliasDescriptorCache |
private static java.util.Map<java.lang.Class<?>,java.lang.Boolean> |
annotatedInterfaceCache |
private static java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.util.Map<java.lang.String,java.util.List<java.lang.String>>> |
attributeAliasesCache |
private static java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.util.List<java.lang.reflect.Method>> |
attributeMethodsCache |
private static java.util.Map<AnnotationUtils.AnnotationCacheKey,java.lang.annotation.Annotation> |
findAnnotationCache |
private static Log |
logger |
private static java.util.Map<AnnotationUtils.AnnotationCacheKey,java.lang.Boolean> |
metaPresentCache |
private static java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.lang.Boolean> |
synthesizableCache |
static java.lang.String |
VALUE
The attribute name for annotations with a single element.
|
Constructor and Description |
---|
AnnotationUtils() |
Modifier and Type | Method and Description |
---|---|
(package private) static java.lang.Object |
adaptValue(java.lang.Object annotatedElement,
java.lang.Object value,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap)
Adapt the given value according to the given class and nested annotation settings.
|
private static boolean |
canExposeSynthesizedMarker(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Check whether we can expose our
SynthesizedAnnotation marker for the given annotation type. |
static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType)
Find a single
Annotation of annotationType on the
supplied AnnotatedElement . |
private static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType,
java.util.Set<java.lang.annotation.Annotation> visited)
Perform the search algorithm for
findAnnotation(AnnotatedElement, Class)
avoiding endless recursion by tracking which annotations have already
been visited. |
static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.Class<?> clazz,
java.lang.Class<A> annotationType)
Find a single
Annotation of annotationType on the
supplied Class , traversing its interfaces, annotations, and
superclasses if the annotation is not directly present on
the given class itself. |
private static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.Class<?> clazz,
java.lang.Class<A> annotationType,
boolean synthesize)
Perform the actual work for
findAnnotation(AnnotatedElement, Class) ,
honoring the synthesize flag. |
private static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.Class<?> clazz,
java.lang.Class<A> annotationType,
java.util.Set<java.lang.annotation.Annotation> visited)
Perform the search algorithm for
findAnnotation(Class, Class) ,
avoiding endless recursion by tracking which annotations have already
been visited. |
static <A extends java.lang.annotation.Annotation> |
findAnnotation(java.lang.reflect.Method method,
java.lang.Class<A> annotationType)
Find a single
Annotation of annotationType on the supplied
Method , traversing its super methods (i.e., from superclasses and
interfaces) if the annotation is not directly present on the given
method itself. |
static java.lang.Class<?> |
findAnnotationDeclaringClass(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<?> clazz)
Find the first
Class in the inheritance hierarchy of the
specified clazz (including the specified clazz itself)
on which an annotation of the specified annotationType is
directly present. |
static java.lang.Class<?> |
findAnnotationDeclaringClassForTypes(java.util.List<java.lang.Class<? extends java.lang.annotation.Annotation>> annotationTypes,
java.lang.Class<?> clazz)
Find the first
Class in the inheritance hierarchy of the
specified clazz (including the specified clazz itself)
on which at least one of the specified annotationTypes is
directly present. |
static <A extends java.lang.annotation.Annotation> |
getAnnotation(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType)
Get a single
Annotation of annotationType from the supplied
AnnotatedElement , where the annotation is either present or
meta-present on the AnnotatedElement . |
(package private) static java.lang.annotation.Annotation |
getAnnotation(java.lang.reflect.AnnotatedElement element,
java.lang.String annotationName)
Get the annotation with the supplied
annotationName on the
supplied element . |
static <A extends java.lang.annotation.Annotation> |
getAnnotation(java.lang.annotation.Annotation ann,
java.lang.Class<A> annotationType)
Get a single
Annotation of annotationType from the supplied
annotation: either the given annotation itself or a direct meta-annotation
thereof. |
static <A extends java.lang.annotation.Annotation> |
getAnnotation(java.lang.reflect.Method method,
java.lang.Class<A> annotationType)
Get a single
Annotation of annotationType from the
supplied Method , where the annotation is either present
or meta-present on the method. |
static AnnotationAttributes |
getAnnotationAttributes(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.annotation.Annotation annotation)
Retrieve the given annotation's attributes as an
AnnotationAttributes map. |
static AnnotationAttributes |
getAnnotationAttributes(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.annotation.Annotation annotation,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap)
Retrieve the given annotation's attributes as an
AnnotationAttributes map. |
static java.util.Map<java.lang.String,java.lang.Object> |
getAnnotationAttributes(java.lang.annotation.Annotation annotation)
Retrieve the given annotation's attributes as a
Map , preserving all
attribute types. |
static java.util.Map<java.lang.String,java.lang.Object> |
getAnnotationAttributes(java.lang.annotation.Annotation annotation,
boolean classValuesAsString)
Retrieve the given annotation's attributes as a
Map . |
static AnnotationAttributes |
getAnnotationAttributes(java.lang.annotation.Annotation annotation,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap)
Retrieve the given annotation's attributes as an
AnnotationAttributes map. |
private static AnnotationAttributes |
getAnnotationAttributes(java.lang.Object annotatedElement,
java.lang.annotation.Annotation annotation,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap) |
static java.lang.annotation.Annotation[] |
getAnnotations(java.lang.reflect.AnnotatedElement annotatedElement)
Get all
Annotations that are present on the
supplied AnnotatedElement . |
static java.lang.annotation.Annotation[] |
getAnnotations(java.lang.reflect.Method method)
Get all
Annotations that are present on the
supplied Method . |
(package private) static java.util.Map<java.lang.String,java.util.List<java.lang.String>> |
getAttributeAliasMap(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Get a map of all attribute aliases declared via
@AliasFor
in the supplied annotation type. |
(package private) static java.util.List<java.lang.String> |
getAttributeAliasNames(java.lang.reflect.Method attribute)
Get the names of the aliased attributes configured via
@AliasFor for the supplied annotation attribute . |
(package private) static java.util.List<java.lang.reflect.Method> |
getAttributeMethods(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Get all methods declared in the supplied
annotationType that
match Java's requirements for annotation attributes. |
(package private) static java.lang.String |
getAttributeOverrideName(java.lang.reflect.Method attribute,
java.lang.Class<? extends java.lang.annotation.Annotation> metaAnnotationType)
Get the name of the overridden attribute configured via
@AliasFor for the supplied annotation attribute . |
static <A extends java.lang.annotation.Annotation> |
getDeclaredRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType)
Get the declared repeatable annotations
of
annotationType from the supplied AnnotatedElement ,
where such annotations are either directly present,
indirectly present, or meta-present on the element. |
static <A extends java.lang.annotation.Annotation> |
getDeclaredRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType,
java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType)
Get the declared repeatable annotations
of
annotationType from the supplied AnnotatedElement ,
where such annotations are either directly present,
indirectly present, or meta-present on the element. |
static java.lang.Object |
getDefaultValue(java.lang.annotation.Annotation annotation)
Retrieve the default value of the
value attribute
of a single-element Annotation, given an annotation instance. |
static java.lang.Object |
getDefaultValue(java.lang.annotation.Annotation annotation,
java.lang.String attributeName)
Retrieve the default value of a named attribute, given an annotation instance.
|
static java.lang.Object |
getDefaultValue(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Retrieve the default value of the
value attribute
of a single-element Annotation, given the annotation type . |
static java.lang.Object |
getDefaultValue(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.String attributeName)
Retrieve the default value of a named attribute, given the
annotation type . |
static <A extends java.lang.annotation.Annotation> |
getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType)
Get the repeatable annotations of
annotationType from the supplied AnnotatedElement , where
such annotations are either present, indirectly present,
or meta-present on the element. |
static <A extends java.lang.annotation.Annotation> |
getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType,
java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType)
Get the repeatable annotations of
annotationType from the supplied AnnotatedElement , where
such annotations are either present, indirectly present,
or meta-present on the element. |
private static <A extends java.lang.annotation.Annotation> |
getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<A> annotationType,
java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType,
boolean declaredMode)
Perform the actual work for
getRepeatableAnnotations(AnnotatedElement, Class, Class)
and getDeclaredRepeatableAnnotations(AnnotatedElement, Class, Class) . |
static java.lang.Object |
getValue(java.lang.annotation.Annotation annotation)
Retrieve the value of the
value attribute of a
single-element Annotation, given an annotation instance. |
static java.lang.Object |
getValue(java.lang.annotation.Annotation annotation,
java.lang.String attributeName)
Retrieve the value of a named attribute, given an annotation instance.
|
(package private) static void |
handleIntrospectionFailure(java.lang.reflect.AnnotatedElement element,
java.lang.Throwable ex)
Handle the supplied annotation introspection exception.
|
static boolean |
isAnnotationDeclaredLocally(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<?> clazz)
Determine whether an annotation of the specified
annotationType
is declared locally (i.e., directly present) on the supplied
clazz . |
static boolean |
isAnnotationInherited(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<?> clazz)
Determine whether an annotation of the specified
annotationType
is present on the supplied clazz and is
inherited (i.e., not
directly present). |
static boolean |
isAnnotationMetaPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<? extends java.lang.annotation.Annotation> metaAnnotationType)
Determine if an annotation of type
metaAnnotationType is
meta-present on the supplied annotationType . |
(package private) static boolean |
isAnnotationTypeMethod(java.lang.reflect.Method method)
Determine if the supplied method is an "annotationType" method.
|
(package private) static boolean |
isAttributeMethod(java.lang.reflect.Method method)
Determine if the supplied
method is an annotation attribute method. |
static boolean |
isInJavaLangAnnotationPackage(java.lang.annotation.Annotation annotation)
Determine if the supplied
Annotation is defined in the core JDK
java.lang.annotation package. |
(package private) static boolean |
isInJavaLangAnnotationPackage(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Determine if the
Annotation with the supplied name is defined
in the core JDK java.lang.annotation package. |
static boolean |
isInJavaLangAnnotationPackage(java.lang.String annotationType)
Determine if the
Annotation with the supplied name is defined
in the core JDK java.lang.annotation package. |
(package private) static boolean |
isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface) |
private static boolean |
isSynthesizable(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Determine if annotations of the supplied
annotationType are
synthesizable (i.e., in need of being wrapped in a dynamic
proxy that provides functionality above that of a standard JDK
annotation). |
static void |
postProcessAnnotationAttributes(java.lang.Object annotatedElement,
AnnotationAttributes attributes,
boolean classValuesAsString)
Post-process the supplied
AnnotationAttributes , preserving nested
annotations as Annotation instances. |
(package private) static void |
postProcessAnnotationAttributes(java.lang.Object annotatedElement,
AnnotationAttributes attributes,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap)
Post-process the supplied
AnnotationAttributes . |
static void |
registerDefaultValues(AnnotationAttributes attributes)
Register the annotation-declared default values for the given attributes,
if available.
|
(package private) static java.lang.Class<? extends java.lang.annotation.Annotation> |
resolveContainerAnnotationType(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Resolve the container type for the supplied repeatable
annotationType . |
(package private) static void |
rethrowAnnotationConfigurationException(java.lang.Throwable ex)
If the supplied throwable is an
AnnotationConfigurationException ,
it will be cast to an AnnotationConfigurationException and thrown,
allowing it to propagate to the caller. |
(package private) static AnnotationAttributes |
retrieveAnnotationAttributes(java.lang.Object annotatedElement,
java.lang.annotation.Annotation annotation,
boolean classValuesAsString,
boolean nestedAnnotationsAsMap)
Retrieve the given annotation's attributes as an
AnnotationAttributes map. |
private static <A extends java.lang.annotation.Annotation> |
searchOnInterfaces(java.lang.reflect.Method method,
java.lang.Class<A> annotationType,
java.lang.Class<?>... ifcs) |
(package private) static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotation(A annotation)
Synthesize an annotation from the supplied
annotation
by wrapping it in a dynamic proxy that transparently enforces
attribute alias semantics for annotation attributes that are
annotated with @AliasFor . |
static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotation(A annotation,
java.lang.reflect.AnnotatedElement annotatedElement)
Synthesize an annotation from the supplied
annotation
by wrapping it in a dynamic proxy that transparently enforces
attribute alias semantics for annotation attributes that are
annotated with @AliasFor . |
(package private) static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotation(A annotation,
java.lang.Object annotatedElement) |
static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotation(java.lang.Class<A> annotationType)
Synthesize an annotation from its default attributes values.
|
static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotation(java.util.Map<java.lang.String,java.lang.Object> attributes,
java.lang.Class<A> annotationType,
java.lang.reflect.AnnotatedElement annotatedElement)
Synthesize an annotation from the supplied map of annotation
attributes by wrapping the map in a dynamic proxy that implements an
annotation of the specified
annotationType and transparently
enforces attribute alias semantics for annotation attributes
that are annotated with @AliasFor . |
(package private) static java.lang.annotation.Annotation[] |
synthesizeAnnotationArray(java.lang.annotation.Annotation[] annotations,
java.lang.Object annotatedElement)
Synthesize an array of annotations from the supplied array
of
annotations by creating a new array of the same size and
type and populating it with synthesized versions of the annotations from the input array. |
(package private) static <A extends java.lang.annotation.Annotation> |
synthesizeAnnotationArray(java.util.Map<java.lang.String,java.lang.Object>[] maps,
java.lang.Class<A> annotationType)
Synthesize an array of annotations from the supplied array
of
maps of annotation attributes by creating a new array of
annotationType with the same size and populating it with
synthesized versions of the maps from the input array. |
public static final java.lang.String VALUE
private static final java.util.Map<AnnotationUtils.AnnotationCacheKey,java.lang.annotation.Annotation> findAnnotationCache
private static final java.util.Map<AnnotationUtils.AnnotationCacheKey,java.lang.Boolean> metaPresentCache
private static final java.util.Map<java.lang.Class<?>,java.lang.Boolean> annotatedInterfaceCache
private static final java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.lang.Boolean> synthesizableCache
private static final java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.util.Map<java.lang.String,java.util.List<java.lang.String>>> attributeAliasesCache
private static final java.util.Map<java.lang.Class<? extends java.lang.annotation.Annotation>,java.util.List<java.lang.reflect.Method>> attributeMethodsCache
private static final java.util.Map<java.lang.reflect.Method,AnnotationUtils.AliasDescriptor> aliasDescriptorCache
@Nullable public static <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.annotation.Annotation ann, java.lang.Class<A> annotationType)
Annotation
of annotationType
from the supplied
annotation: either the given annotation itself or a direct meta-annotation
thereof.
Note that this method supports only a single level of meta-annotations.
For support for arbitrary levels of meta-annotations, use one of the
find*()
methods instead.
ann
- the Annotation to checkannotationType
- the annotation type to look for, both locally and as a meta-annotationnull
if not found@Nullable public static <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType)
Annotation
of annotationType
from the supplied
AnnotatedElement
, where the annotation is either present or
meta-present on the AnnotatedElement
.
Note that this method supports only a single level of meta-annotations.
For support for arbitrary levels of meta-annotations, use
findAnnotation(AnnotatedElement, Class)
instead.
annotatedElement
- the AnnotatedElement
from which to get the annotationannotationType
- the annotation type to look for, both locally and as a meta-annotationnull
if not found@Nullable public static <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.reflect.Method method, java.lang.Class<A> annotationType)
Annotation
of annotationType
from the
supplied Method
, where the annotation is either present
or meta-present on the method.
Correctly handles bridge 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
findAnnotation(Method, Class)
instead.
method
- the method to look for annotations onannotationType
- the annotation type to look fornull
if not foundBridgeMethodResolver.findBridgedMethod(Method)
,
getAnnotation(AnnotatedElement, Class)
@Nullable public static java.lang.annotation.Annotation[] getAnnotations(java.lang.reflect.AnnotatedElement annotatedElement)
Annotations
that are present on the
supplied AnnotatedElement
.
Meta-annotations will not be searched.
annotatedElement
- the Method, Constructor or Field to retrieve annotations fromnull
if not
resolvable (e.g. because nested Class values in annotation attributes
failed to resolve at runtime)AnnotatedElement.getAnnotations()
@Nullable public static java.lang.annotation.Annotation[] getAnnotations(java.lang.reflect.Method method)
Annotations
that are present on the
supplied Method
.
Correctly handles bridge Methods
generated by the compiler.
Meta-annotations will not be searched.
method
- the Method to retrieve annotations fromnull
if not
resolvable (e.g. because nested Class values in annotation attributes
failed to resolve at runtime)BridgeMethodResolver.findBridgedMethod(Method)
,
AnnotatedElement.getAnnotations()
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType)
annotationType
from the supplied AnnotatedElement
, where
such annotations are either present, indirectly present,
or meta-present on the element.
This method mimics the functionality of Java 8's
AnnotatedElement.getAnnotationsByType(Class)
with support for automatic detection of a container annotation
declared via @Repeatable
(when running on
Java 8 or higher) and with additional support for meta-annotations.
Handles both single annotations and annotations nested within a container annotation.
Correctly handles bridge methods generated by the
compiler if the supplied element is a Method
.
Meta-annotations will be searched if the annotation is not present on the supplied element.
annotatedElement
- the element to look for annotations onannotationType
- the annotation type to look fornull
)getRepeatableAnnotations(AnnotatedElement, Class, Class)
,
getDeclaredRepeatableAnnotations(AnnotatedElement, Class, Class)
,
AnnotatedElementUtils.getMergedRepeatableAnnotations(AnnotatedElement, Class)
,
BridgeMethodResolver.findBridgedMethod(java.lang.reflect.Method)
,
Repeatable
,
AnnotatedElement.getAnnotationsByType(java.lang.Class<T>)
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType, @Nullable java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType)
annotationType
from the supplied AnnotatedElement
, where
such annotations are either present, indirectly present,
or meta-present on the element.
This method mimics the functionality of Java 8's
AnnotatedElement.getAnnotationsByType(Class)
with additional support for meta-annotations.
Handles both single annotations and annotations nested within a container annotation.
Correctly handles bridge methods generated by the
compiler if the supplied element is a Method
.
Meta-annotations will be searched if the annotation is not present on the supplied element.
annotatedElement
- the element to look for annotations onannotationType
- the annotation type to look forcontainerAnnotationType
- the type of the container that holds
the annotations; may be null
if a container is not supported
or if it should be looked up via @Repeatable
when running on Java 8 or highernull
)getRepeatableAnnotations(AnnotatedElement, Class)
,
getDeclaredRepeatableAnnotations(AnnotatedElement, Class)
,
getDeclaredRepeatableAnnotations(AnnotatedElement, Class, Class)
,
AnnotatedElementUtils.getMergedRepeatableAnnotations(AnnotatedElement, Class, Class)
,
BridgeMethodResolver.findBridgedMethod(java.lang.reflect.Method)
,
Repeatable
,
AnnotatedElement.getAnnotationsByType(java.lang.Class<T>)
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getDeclaredRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType)
annotationType
from the supplied AnnotatedElement
,
where such annotations are either directly present,
indirectly present, or meta-present on the element.
This method mimics the functionality of Java 8's
AnnotatedElement.getDeclaredAnnotationsByType(Class)
with support for automatic detection of a container annotation
declared via @Repeatable
(when running on
Java 8 or higher) and with additional support for meta-annotations.
Handles both single annotations and annotations nested within a container annotation.
Correctly handles bridge methods generated by the
compiler if the supplied element is a Method
.
Meta-annotations will be searched if the annotation is not present on the supplied element.
annotatedElement
- the element to look for annotations onannotationType
- the annotation type to look fornull
)getRepeatableAnnotations(AnnotatedElement, Class)
,
getRepeatableAnnotations(AnnotatedElement, Class, Class)
,
getDeclaredRepeatableAnnotations(AnnotatedElement, Class, Class)
,
AnnotatedElementUtils.getMergedRepeatableAnnotations(AnnotatedElement, Class)
,
BridgeMethodResolver.findBridgedMethod(java.lang.reflect.Method)
,
Repeatable
,
AnnotatedElement.getDeclaredAnnotationsByType(java.lang.Class<T>)
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getDeclaredRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType, @Nullable java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType)
annotationType
from the supplied AnnotatedElement
,
where such annotations are either directly present,
indirectly present, or meta-present on the element.
This method mimics the functionality of Java 8's
AnnotatedElement.getDeclaredAnnotationsByType(Class)
with additional support for meta-annotations.
Handles both single annotations and annotations nested within a container annotation.
Correctly handles bridge methods generated by the
compiler if the supplied element is a Method
.
Meta-annotations will be searched if the annotation is not present on the supplied element.
annotatedElement
- the element to look for annotations onannotationType
- the annotation type to look forcontainerAnnotationType
- the type of the container that holds
the annotations; may be null
if a container is not supported
or if it should be looked up via @Repeatable
when running on Java 8 or highernull
)getRepeatableAnnotations(AnnotatedElement, Class)
,
getRepeatableAnnotations(AnnotatedElement, Class, Class)
,
getDeclaredRepeatableAnnotations(AnnotatedElement, Class)
,
AnnotatedElementUtils.getMergedRepeatableAnnotations(AnnotatedElement, Class, Class)
,
BridgeMethodResolver.findBridgedMethod(java.lang.reflect.Method)
,
Repeatable
,
AnnotatedElement.getDeclaredAnnotationsByType(java.lang.Class<T>)
private static <A extends java.lang.annotation.Annotation> java.util.Set<A> getRepeatableAnnotations(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType, @Nullable java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType, boolean declaredMode)
getRepeatableAnnotations(AnnotatedElement, Class, Class)
and getDeclaredRepeatableAnnotations(AnnotatedElement, Class, Class)
.
Correctly handles bridge methods generated by the
compiler if the supplied element is a Method
.
Meta-annotations will be searched if the annotation is not present on the supplied element.
annotatedElement
- the element to look for annotations onannotationType
- the annotation type to look forcontainerAnnotationType
- the type of the container that holds
the annotations; may be null
if a container is not supported
or if it should be looked up via @Repeatable
when running on Java 8 or higherdeclaredMode
- true
if only declared annotations (i.e.,
directly or indirectly present) should be considerednull
)BridgeMethodResolver.findBridgedMethod(java.lang.reflect.Method)
,
Repeatable
@Nullable public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType)
Annotation
of annotationType
on the
supplied AnnotatedElement
.
Meta-annotations will be searched if the annotation is not directly present on the supplied element.
Warning: this method operates generically on
annotated elements. In other words, this method does not execute
specialized search algorithms for classes or methods. If you require
the more specific semantics of findAnnotation(Class, Class)
or findAnnotation(Method, Class)
, invoke one of those methods
instead.
annotatedElement
- the AnnotatedElement
on which to find the annotationannotationType
- the annotation type to look for, both locally and as a meta-annotationnull
if not found@Nullable private static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<A> annotationType, java.util.Set<java.lang.annotation.Annotation> visited)
findAnnotation(AnnotatedElement, Class)
avoiding endless recursion by tracking which annotations have already
been visited.annotatedElement
- the AnnotatedElement
on which to find the annotationannotationType
- the annotation type to look for, both locally and as a meta-annotationvisited
- the set of annotations that have already been visitednull
if not found@Nullable public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.reflect.Method method, @Nullable java.lang.Class<A> annotationType)
Annotation
of annotationType
on the supplied
Method
, traversing its super methods (i.e., from superclasses and
interfaces) if the annotation is not directly present on the given
method itself.
Correctly handles bridge Methods
generated by the compiler.
Meta-annotations will be searched if the annotation is not directly present on the method.
Annotations on methods are not inherited by default, so we need to handle this explicitly.
method
- the method to look for annotations onannotationType
- the annotation type to look fornull
if not foundgetAnnotation(Method, Class)
@Nullable private static <A extends java.lang.annotation.Annotation> A searchOnInterfaces(java.lang.reflect.Method method, java.lang.Class<A> annotationType, java.lang.Class<?>... ifcs)
static boolean isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface)
@Nullable public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.Class<?> clazz, java.lang.Class<A> annotationType)
Annotation
of annotationType
on the
supplied Class
, traversing its interfaces, annotations, and
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 inherited
as well
as meta-annotations and annotations on interfaces.
The algorithm operates as follows:
Note: in this context, the term recursively means that the search process continues by returning to step #1 with the current interface, annotation, or superclass as the class to look for annotations on.
clazz
- the class to look for annotations onannotationType
- the type of annotation to look fornull
if not found@Nullable private static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.Class<?> clazz, @Nullable java.lang.Class<A> annotationType, boolean synthesize)
findAnnotation(AnnotatedElement, Class)
,
honoring the synthesize
flag.clazz
- the class to look for annotations onannotationType
- the type of annotation to look forsynthesize
- true
if the result should be
synthesizednull
if not found@Nullable private static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.Class<?> clazz, java.lang.Class<A> annotationType, java.util.Set<java.lang.annotation.Annotation> visited)
findAnnotation(Class, Class)
,
avoiding endless recursion by tracking which annotations have already
been visited.clazz
- the class to look for annotations onannotationType
- the type of annotation to look forvisited
- the set of annotations that have already been visitednull
if not found@Nullable public static java.lang.Class<?> findAnnotationDeclaringClass(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, @Nullable java.lang.Class<?> clazz)
Class
in the inheritance hierarchy of the
specified clazz
(including the specified clazz
itself)
on which an annotation of the specified annotationType
is
directly present.
If the supplied 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 Class
API does not provide a mechanism for
determining which class in an inheritance hierarchy actually declares
an Annotation
, so we need to handle this explicitly.
annotationType
- the annotation type to look forclazz
- the class to check for the annotation on (may be null
)Class
in the inheritance hierarchy that
declares an annotation of the specified annotationType
, or
null
if not foundClass.isAnnotationPresent(Class)
,
Class.getDeclaredAnnotations()
,
findAnnotationDeclaringClassForTypes(List, Class)
,
isAnnotationDeclaredLocally(Class, Class)
@Nullable public static java.lang.Class<?> findAnnotationDeclaringClassForTypes(java.util.List<java.lang.Class<? extends java.lang.annotation.Annotation>> annotationTypes, @Nullable java.lang.Class<?> clazz)
Class
in the inheritance hierarchy of the
specified clazz
(including the specified clazz
itself)
on which at least one of the specified annotationTypes
is
directly present.
If the supplied 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 Class
API does not provide a mechanism for
determining which class in an inheritance hierarchy actually declares
one of several candidate annotations, so we
need to handle this explicitly.
annotationTypes
- the annotation types to look forclazz
- the class to check for the annotations on, or null
Class
in the inheritance hierarchy that
declares an annotation of at least one of the specified
annotationTypes
, or null
if not foundClass.isAnnotationPresent(Class)
,
Class.getDeclaredAnnotations()
,
findAnnotationDeclaringClass(Class, Class)
,
isAnnotationDeclaredLocally(Class, Class)
public static boolean isAnnotationDeclaredLocally(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, java.lang.Class<?> clazz)
annotationType
is declared locally (i.e., directly present) on the supplied
clazz
.
The supplied Class
may represent any type.
Meta-annotations will not be searched.
Note: This method does not determine if the annotation
is inherited. For greater
clarity regarding inherited annotations, consider using
isAnnotationInherited(Class, Class)
instead.
annotationType
- the annotation type to look forclazz
- the class to check for the annotation ontrue
if an annotation of the specified annotationType
is directly presentClass.getDeclaredAnnotations()
,
Class.getDeclaredAnnotation(Class)
,
isAnnotationInherited(Class, Class)
public static boolean isAnnotationInherited(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, java.lang.Class<?> clazz)
annotationType
is present on the supplied clazz
and is
inherited (i.e., not
directly present).
Meta-annotations will not be searched.
If the supplied 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 javadoc
for the @Inherited
meta-annotation for further details regarding
annotation inheritance.
annotationType
- the annotation type to look forclazz
- the class to check for the annotation ontrue
if an annotation of the specified annotationType
is present and inheritedClass.isAnnotationPresent(Class)
,
isAnnotationDeclaredLocally(Class, Class)
public static boolean isAnnotationMetaPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, @Nullable java.lang.Class<? extends java.lang.annotation.Annotation> metaAnnotationType)
metaAnnotationType
is
meta-present on the supplied annotationType
.annotationType
- the annotation type to search onmetaAnnotationType
- the type of meta-annotation to search fortrue
if such an annotation is meta-presentpublic static boolean isInJavaLangAnnotationPackage(@Nullable java.lang.annotation.Annotation annotation)
Annotation
is defined in the core JDK
java.lang.annotation
package.annotation
- the annotation to checktrue
if the annotation is in the java.lang.annotation
packagestatic boolean isInJavaLangAnnotationPackage(@Nullable java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
Annotation
with the supplied name is defined
in the core JDK java.lang.annotation
package.annotationType
- the annotation type to checktrue
if the annotation is in the java.lang.annotation
packagepublic static boolean isInJavaLangAnnotationPackage(@Nullable java.lang.String annotationType)
Annotation
with the supplied name is defined
in the core JDK java.lang.annotation
package.annotationType
- the name of the annotation type to checktrue
if the annotation is in the java.lang.annotation
packagepublic static java.util.Map<java.lang.String,java.lang.Object> getAnnotationAttributes(java.lang.annotation.Annotation annotation)
Map
, preserving all
attribute types.
Equivalent to calling getAnnotationAttributes(Annotation, boolean, boolean)
with the classValuesAsString
and nestedAnnotationsAsMap
parameters
set to false
.
Note: This method actually returns an AnnotationAttributes
instance.
However, the Map
signature has been preserved for binary compatibility.
annotation
- the annotation to retrieve the attributes fornull
)getAnnotationAttributes(AnnotatedElement, Annotation)
,
getAnnotationAttributes(Annotation, boolean, boolean)
,
getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
public static java.util.Map<java.lang.String,java.lang.Object> getAnnotationAttributes(java.lang.annotation.Annotation annotation, boolean classValuesAsString)
Map
.
Equivalent to calling getAnnotationAttributes(Annotation, boolean, boolean)
with the nestedAnnotationsAsMap
parameter set to false
.
Note: This method actually returns an AnnotationAttributes
instance.
However, the Map
signature has been preserved for binary compatibility.
annotation
- the annotation to retrieve the attributes forclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnull
)getAnnotationAttributes(Annotation, boolean, boolean)
public static AnnotationAttributes getAnnotationAttributes(java.lang.annotation.Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
AnnotationAttributes
map.
This method provides fully recursive annotation reading capabilities on par with
the reflection-based StandardAnnotationMetadata
.
annotation
- the annotation to retrieve the attributes forclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to convert nested annotations into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
) or to preserve them as
Annotation
instancesnull
)public static AnnotationAttributes getAnnotationAttributes(@Nullable java.lang.reflect.AnnotatedElement annotatedElement, java.lang.annotation.Annotation annotation)
AnnotationAttributes
map.
Equivalent to calling getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
with the classValuesAsString
and nestedAnnotationsAsMap
parameters
set to false
.
annotatedElement
- the element that is annotated with the supplied annotation;
may be null
if unknownannotation
- the annotation to retrieve the attributes fornull
)getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
public static AnnotationAttributes getAnnotationAttributes(@Nullable java.lang.reflect.AnnotatedElement annotatedElement, java.lang.annotation.Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
AnnotationAttributes
map.
This method provides fully recursive annotation reading capabilities on par with
the reflection-based StandardAnnotationMetadata
.
annotatedElement
- the element that is annotated with the supplied annotation;
may be null
if unknownannotation
- the annotation to retrieve the attributes forclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to convert nested annotations into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
) or to preserve them as
Annotation
instancesnull
)private static AnnotationAttributes getAnnotationAttributes(@Nullable java.lang.Object annotatedElement, java.lang.annotation.Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
static AnnotationAttributes retrieveAnnotationAttributes(@Nullable java.lang.Object annotatedElement, java.lang.annotation.Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
AnnotationAttributes
map.
This method provides fully recursive annotation reading capabilities on par with
the reflection-based StandardAnnotationMetadata
.
NOTE: This variant of getAnnotationAttributes()
is
only intended for use within the framework. The following special rules apply:
@AliasFor
semantics.annotatedElement
- the element that is annotated with the supplied annotation;
may be null
if unknownannotation
- the annotation to retrieve the attributes forclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to convert nested annotations into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
) or to preserve them as
Annotation
instancesnull
)postProcessAnnotationAttributes(java.lang.Object, org.springframework.core.annotation.AnnotationAttributes, boolean)
@Nullable static java.lang.Object adaptValue(@Nullable java.lang.Object annotatedElement, @Nullable java.lang.Object value, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
Nested annotations will be synthesized.
annotatedElement
- the element that is annotated, used for contextual
logging; may be null
if unknownvalue
- the annotation attribute valueclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to convert nested annotations into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
) or to preserve them as
Annotation
instancespublic static void registerDefaultValues(AnnotationAttributes attributes)
attributes
- the annotation attributes to processpublic static void postProcessAnnotationAttributes(@Nullable java.lang.Object annotatedElement, AnnotationAttributes attributes, boolean classValuesAsString)
AnnotationAttributes
, preserving nested
annotations as Annotation
instances.
Specifically, this method enforces attribute alias semantics
for annotation attributes that are annotated with @AliasFor
and replaces default value placeholders with their original default values.
annotatedElement
- the element that is annotated with an annotation or
annotation hierarchy from which the supplied attributes were created;
may be null
if unknownattributes
- the annotation attributes to post-processclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencespostProcessAnnotationAttributes(Object, AnnotationAttributes, boolean, boolean)
,
getDefaultValue(Class, String)
static void postProcessAnnotationAttributes(@Nullable java.lang.Object annotatedElement, @Nullable AnnotationAttributes attributes, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
AnnotationAttributes
.
Specifically, this method enforces attribute alias semantics
for annotation attributes that are annotated with @AliasFor
and replaces default value placeholders with their original default values.
annotatedElement
- the element that is annotated with an annotation or
annotation hierarchy from which the supplied attributes were created;
may be null
if unknownattributes
- the annotation attributes to post-processclassValuesAsString
- whether to convert Class references into Strings (for
compatibility with AnnotationMetadata
)
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to convert nested annotations into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
) or to preserve them as
Annotation
instancesretrieveAnnotationAttributes(Object, Annotation, boolean, boolean)
,
getDefaultValue(Class, String)
@Nullable public static java.lang.Object getValue(java.lang.annotation.Annotation annotation)
value
attribute of a
single-element Annotation, given an annotation instance.annotation
- the annotation instance from which to retrieve the valuenull
if not found unless the attribute
value cannot be retrieved due to an AnnotationConfigurationException
,
in which case such an exception will be rethrowngetValue(Annotation, String)
@Nullable public static java.lang.Object getValue(@Nullable java.lang.annotation.Annotation annotation, @Nullable java.lang.String attributeName)
annotation
- the annotation instance from which to retrieve the valueattributeName
- the name of the attribute value to retrievenull
if not found unless the attribute
value cannot be retrieved due to an AnnotationConfigurationException
,
in which case such an exception will be rethrowngetValue(Annotation)
,
rethrowAnnotationConfigurationException(Throwable)
@Nullable public static java.lang.Object getDefaultValue(java.lang.annotation.Annotation annotation)
value
attribute
of a single-element Annotation, given an annotation instance.annotation
- the annotation instance from which to retrieve the default valuenull
if not foundgetDefaultValue(Annotation, String)
@Nullable public static java.lang.Object getDefaultValue(@Nullable java.lang.annotation.Annotation annotation, @Nullable java.lang.String attributeName)
annotation
- the annotation instance from which to retrieve the default valueattributeName
- the name of the attribute value to retrievenull
if not foundgetDefaultValue(Class, String)
@Nullable public static java.lang.Object getDefaultValue(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
value
attribute
of a single-element Annotation, given the annotation type
.annotationType
- the annotation type for which the default value should be retrievednull
if not foundgetDefaultValue(Class, String)
@Nullable public static java.lang.Object getDefaultValue(@Nullable java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, @Nullable java.lang.String attributeName)
annotation type
.annotationType
- the annotation type for which the default value should be retrievedattributeName
- the name of the attribute value to retrieve.null
if not foundgetDefaultValue(Annotation, String)
static <A extends java.lang.annotation.Annotation> A synthesizeAnnotation(A annotation)
annotation
by wrapping it in a dynamic proxy that transparently enforces
attribute alias semantics for annotation attributes that are
annotated with @AliasFor
.annotation
- the annotation to synthesizenull
if the supplied annotation is
null
; otherwise, the supplied annotation unmodifiedAnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Annotation, AnnotatedElement)
public static <A extends java.lang.annotation.Annotation> A synthesizeAnnotation(A annotation, @Nullable java.lang.reflect.AnnotatedElement annotatedElement)
annotation
by wrapping it in a dynamic proxy that transparently enforces
attribute alias semantics for annotation attributes that are
annotated with @AliasFor
.annotation
- the annotation to synthesizeannotatedElement
- the element that is annotated with the supplied
annotation; may be null
if unknownnull
if the supplied annotation is
null
; otherwise the supplied annotation unmodifiedAnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Map, Class, AnnotatedElement)
,
synthesizeAnnotation(Class)
static <A extends java.lang.annotation.Annotation> A synthesizeAnnotation(A annotation, @Nullable java.lang.Object annotatedElement)
public static <A extends java.lang.annotation.Annotation> A synthesizeAnnotation(java.util.Map<java.lang.String,java.lang.Object> attributes, java.lang.Class<A> annotationType, @Nullable java.lang.reflect.AnnotatedElement annotatedElement)
annotationType
and transparently
enforces attribute alias semantics for annotation attributes
that are annotated with @AliasFor
.
The supplied map must contain a key-value pair for every attribute
defined in the supplied annotationType
that is not aliased or
does not have a default value. Nested maps and nested arrays of maps
will be recursively synthesized into nested annotations or nested
arrays of annotations, respectively.
Note that AnnotationAttributes
is a specialized type of
Map
that is an ideal candidate for this method's
attributes
argument.
attributes
- the map of annotation attributes to synthesizeannotationType
- the type of annotation to synthesizeannotatedElement
- the element that is annotated with the annotation
corresponding to the supplied attributes; may be null
if unknownjava.lang.IllegalArgumentException
- if a required attribute is missing or if an
attribute is not of the correct typeAnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Annotation, AnnotatedElement)
,
synthesizeAnnotation(Class)
,
getAnnotationAttributes(AnnotatedElement, Annotation)
,
getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
public static <A extends java.lang.annotation.Annotation> A synthesizeAnnotation(java.lang.Class<A> annotationType)
This method simply delegates to
synthesizeAnnotation(Map, Class, AnnotatedElement)
,
supplying an empty map for the source attribute values and null
for the AnnotatedElement
.
annotationType
- the type of annotation to synthesizejava.lang.IllegalArgumentException
- if a required attribute is missingAnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Map, Class, AnnotatedElement)
,
synthesizeAnnotation(Annotation, AnnotatedElement)
static java.lang.annotation.Annotation[] synthesizeAnnotationArray(java.lang.annotation.Annotation[] annotations, @Nullable java.lang.Object annotatedElement)
annotations
by creating a new array of the same size and
type and populating it with synthesized versions of the annotations from the input array.annotations
- the array of annotations to synthesizeannotatedElement
- the element that is annotated with the supplied
array of annotations; may be null
if unknownnull
if
the supplied array is null
AnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Annotation, AnnotatedElement)
,
synthesizeAnnotation(Map, Class, AnnotatedElement)
@Nullable static <A extends java.lang.annotation.Annotation> A[] synthesizeAnnotationArray(@Nullable java.util.Map<java.lang.String,java.lang.Object>[] maps, java.lang.Class<A> annotationType)
maps
of annotation attributes by creating a new array of
annotationType
with the same size and populating it with
synthesized versions of the maps from the input array.maps
- the array of maps of annotation attributes to synthesizeannotationType
- the type of annotations to synthesize
(never null
)null
if
the supplied array is null
AnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedsynthesizeAnnotation(Map, Class, AnnotatedElement)
,
synthesizeAnnotationArray(Annotation[], Object)
static java.util.Map<java.lang.String,java.util.List<java.lang.String>> getAttributeAliasMap(@Nullable java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
@AliasFor
in the supplied annotation type.
The map is keyed by attribute name with each value representing a list of names of aliased attributes.
For explicit alias pairs such as x and y (i.e., where x
is an @AliasFor("y")
and y is an @AliasFor("x")
, there
will be two entries in the map: x -> (y)
and y -> (x)
.
For implicit aliases (i.e., attributes that are declared
as attribute overrides for the same attribute in the same meta-annotation),
there will be n entries in the map. For example, if x, y, and z are
implicit aliases, the map will contain the following entries:
x -> (y, z)
, y -> (x, z)
, z -> (x, y)
.
An empty return value implies that the annotation does not declare any attribute aliases.
annotationType
- the annotation type to find attribute aliases innull
)private static boolean canExposeSynthesizedMarker(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
SynthesizedAnnotation
marker for the given annotation type.annotationType
- the annotation type that we are about to create a synthesized proxy forprivate static boolean isSynthesizable(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
annotationType
are
synthesizable (i.e., in need of being wrapped in a dynamic
proxy that provides functionality above that of a standard JDK
annotation).
Specifically, an annotation is synthesizable if it declares
any attributes that are configured as aliased pairs via
@AliasFor
or if any nested annotations used by the
annotation declare such aliased pairs.
SynthesizedAnnotation
,
SynthesizedAnnotationInvocationHandler
static java.util.List<java.lang.String> getAttributeAliasNames(java.lang.reflect.Method attribute)
@AliasFor
for the supplied annotation attribute
.attribute
- the attribute to find aliases fornull
, though
potentially empty)java.lang.IllegalArgumentException
- if the supplied attribute method is
null
or not from an annotationAnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedgetAttributeOverrideName(Method, Class)
@Nullable static java.lang.String getAttributeOverrideName(java.lang.reflect.Method attribute, @Nullable java.lang.Class<? extends java.lang.annotation.Annotation> metaAnnotationType)
@AliasFor
for the supplied annotation attribute
.attribute
- the attribute from which to retrieve the override
(never null
)metaAnnotationType
- the type of meta-annotation in which the
overridden attribute is allowed to be declarednull
if not
found or not applicable for the specified meta-annotation typejava.lang.IllegalArgumentException
- if the supplied attribute method is
null
or not from an annotation, or if the supplied meta-annotation
type is null
or Annotation
AnnotationConfigurationException
- if invalid configuration of
@AliasFor
is detectedstatic java.util.List<java.lang.reflect.Method> getAttributeMethods(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
annotationType
that
match Java's requirements for annotation attributes.
All methods in the returned list will be made accessible.
annotationType
- the type in which to search for attribute methods
(never null
)null
, though potentially empty)@Nullable static java.lang.annotation.Annotation getAnnotation(java.lang.reflect.AnnotatedElement element, java.lang.String annotationName)
annotationName
on the
supplied element
.element
- the element to search onannotationName
- the fully qualified class name of the annotation
type to findnull
otherwisestatic boolean isAttributeMethod(@Nullable java.lang.reflect.Method method)
method
is an annotation attribute method.method
- the method to checktrue
if the method is an attribute methodstatic boolean isAnnotationTypeMethod(@Nullable java.lang.reflect.Method method)
true
if the method is an "annotationType" methodAnnotation.annotationType()
@Nullable static java.lang.Class<? extends java.lang.annotation.Annotation> resolveContainerAnnotationType(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
annotationType
.
Automatically detects a container annotation declared via
Repeatable
. If the supplied annotation type
is not annotated with @Repeatable
, this method simply returns
null
.
static void rethrowAnnotationConfigurationException(java.lang.Throwable ex)
AnnotationConfigurationException
,
it will be cast to an AnnotationConfigurationException
and thrown,
allowing it to propagate to the caller.
Otherwise, this method does nothing.
ex
- the throwable to inspectstatic void handleIntrospectionFailure(@Nullable java.lang.reflect.AnnotatedElement element, java.lang.Throwable ex)
If the supplied exception is an AnnotationConfigurationException
,
it will simply be thrown, allowing it to propagate to the caller, and
nothing will be logged.
Otherwise, this method logs an introspection failure (in particular
TypeNotPresentExceptions
) before moving on, assuming nested
Class values were not resolvable within annotation attributes and
thereby effectively pretending there were no annotations on the specified
element.
element
- the element that we tried to introspect annotations onex
- the exception that we encounteredrethrowAnnotationConfigurationException(java.lang.Throwable)