public abstract class AnnotationUtils
extends java.lang.Object
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)
).
AccessibleObject.getAnnotations()
,
Method.getAnnotation(Class)
Modifier and Type | Class and Description |
---|---|
private static class |
AnnotationUtils.AnnotationCollector<A extends java.lang.annotation.Annotation> |
Modifier and Type | Field and Description |
---|---|
private static java.util.Map<java.lang.Class<?>,java.lang.Boolean> |
annotatedInterfaceCache |
private static Log |
logger |
static java.lang.String |
VALUE
The attribute name for annotations with a single element
|
Constructor and Description |
---|
AnnotationUtils() |
Modifier and Type | Method and Description |
---|---|
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 present on the given class
itself. |
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 from the supplied
Method , traversing its super methods (i.e., from superclasses and
interfaces) if no annotation can be found 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) which declares an annotation for the
specified annotationType , or null if not found. |
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) which declares
at least one of the specified annotationTypes , or null if
none of the specified annotation types could be found. |
static <T extends java.lang.annotation.Annotation> |
getAnnotation(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<T> annotationType)
Get a single
Annotation of annotationType from the supplied
Method, Constructor or Field. |
static <T extends java.lang.annotation.Annotation> |
getAnnotation(java.lang.annotation.Annotation ann,
java.lang.Class<T> annotationType)
Get a single
Annotation of annotationType from the supplied
annotation: either the given annotation itself or a 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 . |
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 as-is. |
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 structure. |
static java.lang.annotation.Annotation[] |
getAnnotations(java.lang.reflect.Method method)
Get all
Annotations from the supplied Method . |
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> |
getRepeatableAnnotation(java.lang.reflect.AnnotatedElement annotatedElement,
java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType,
java.lang.Class<A> annotationType)
Get the possibly repeating
Annotation s of annotationType from the
supplied AnnotatedElement . |
static <A extends java.lang.annotation.Annotation> |
getRepeatableAnnotation(java.lang.reflect.Method method,
java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType,
java.lang.Class<A> annotationType)
Get the possibly repeating
Annotation s of annotationType from the
supplied Method . |
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.
|
static boolean |
isAnnotationDeclaredLocally(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<?> clazz)
Determine whether an annotation for the specified
annotationType is
declared locally on the supplied clazz . |
static boolean |
isAnnotationInherited(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
java.lang.Class<?> clazz)
Determine whether an annotation for the specified
annotationType is present
on the supplied clazz and is inherited
(i.e., not declared locally for the class). |
static boolean |
isInJavaLangAnnotationPackage(java.lang.annotation.Annotation annotation)
Determine if the supplied
Annotation is defined in the core JDK
java.lang.annotation package. |
private static boolean |
isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface) |
private static <A extends java.lang.annotation.Annotation> |
searchOnInterfaces(java.lang.reflect.Method method,
java.lang.Class<A> annotationType,
java.lang.Class<?>[] ifcs) |
public static final java.lang.String VALUE
private static final Log logger
private static final java.util.Map<java.lang.Class<?>,java.lang.Boolean> annotatedInterfaceCache
public static <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.annotation.Annotation ann, java.lang.Class<T> annotationType)
Annotation
of annotationType
from the supplied
annotation: either the given annotation itself or a meta-annotation thereof.ann
- the Annotation to checkannotationType
- the annotation type to look for, both locally and as a meta-annotationnull
if none foundpublic static <T extends java.lang.annotation.Annotation> T getAnnotation(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<T> annotationType)
Annotation
of annotationType
from the supplied
Method, Constructor or Field. Meta-annotations will be searched if the annotation
is not declared locally on the supplied element.annotatedElement
- the Method, Constructor or Field from which to get the annotationannotationType
- the annotation type to look for, both locally and as a meta-annotationnull
if none foundpublic static java.lang.annotation.Annotation[] getAnnotations(java.lang.reflect.Method method)
Annotations
from the supplied Method
.
Correctly handles bridge Methods
generated by the compiler.
method
- the method to look for annotations onBridgeMethodResolver.findBridgedMethod(Method)
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
.
Correctly handles bridge Methods
generated by the compiler.
method
- the method to look for annotations onannotationType
- the annotation type to look forBridgeMethodResolver.findBridgedMethod(Method)
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getRepeatableAnnotation(java.lang.reflect.Method method, java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType, java.lang.Class<A> annotationType)
Annotation
s of annotationType
from the
supplied Method
. Deals with both a single direct annotation and repeating
annotations nested within a containing annotation.
Correctly handles bridge Methods
generated by the compiler.
method
- the method to look for annotations oncontainerAnnotationType
- the class of the container that holds the annotationsannotationType
- the annotation type to look forBridgeMethodResolver.findBridgedMethod(Method)
public static <A extends java.lang.annotation.Annotation> java.util.Set<A> getRepeatableAnnotation(java.lang.reflect.AnnotatedElement annotatedElement, java.lang.Class<? extends java.lang.annotation.Annotation> containerAnnotationType, java.lang.Class<A> annotationType)
Annotation
s of annotationType
from the
supplied AnnotatedElement
. Deals with both a single direct annotation and
repeating annotations nested within a containing annotation.
Correctly handles bridge Methods
generated by the compiler.
annotatedElement
- the element to look for annotations oncontainerAnnotationType
- the class of the container that holds the annotationsannotationType
- the annotation type to look forBridgeMethodResolver.findBridgedMethod(Method)
public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.reflect.Method method, java.lang.Class<A> annotationType)
Annotation
of annotationType
from the supplied
Method
, traversing its super methods (i.e., from superclasses and
interfaces) if no annotation can be found on the given method itself.
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 noneprivate static <A extends java.lang.annotation.Annotation> A searchOnInterfaces(java.lang.reflect.Method method, java.lang.Class<A> annotationType, java.lang.Class<?>[] ifcs)
private static boolean isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface)
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 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 foundprivate 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 foundpublic static java.lang.Class<?> findAnnotationDeclaringClass(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, java.lang.Class<?> clazz)
Class
in the inheritance hierarchy of the specified clazz
(including the specified clazz
itself) which declares an annotation for the
specified annotationType
, or null
if not found. If the supplied
clazz
is null
, null
will be returned.
If the supplied clazz
is an interface, only the interface itself will be checked;
the inheritance hierarchy for interfaces will not be traversed.
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 for, both locally and as a meta-annotationclazz
- the class on which to check for the annotation (may be null
)Class
in the inheritance hierarchy of the specified clazz
which declares an annotation for the specified annotationType
, or null
if not foundClass.isAnnotationPresent(Class)
,
Class.getDeclaredAnnotations()
,
findAnnotationDeclaringClassForTypes(List, Class)
,
isAnnotationDeclaredLocally(Class, Class)
public static java.lang.Class<?> findAnnotationDeclaringClassForTypes(java.util.List<java.lang.Class<? extends java.lang.annotation.Annotation>> annotationTypes, java.lang.Class<?> clazz)
Class
in the inheritance hierarchy of the specified
clazz
(including the specified clazz
itself) which declares
at least one of the specified annotationTypes
, or null
if
none of the specified annotation types could be found.
If the supplied clazz
is null
, null
will be
returned.
If the supplied clazz
is an interface, only the interface itself
will be checked; the inheritance hierarchy for interfaces will not be traversed.
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 list of Class objects corresponding to the
annotation typesclazz
- the Class object corresponding to the class on which to check
for the annotations, or null
Class
in the inheritance hierarchy of the specified
clazz
which 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 on the supplied clazz
. The supplied Class
may represent any type.
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 Class object corresponding to the annotation typeclazz
- the Class object corresponding to the class on which to check for the annotationtrue
if an annotation for the specified annotationType
is declared locally on the supplied clazz
Class.getDeclaredAnnotations()
,
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 declared locally for the class).
If the supplied clazz
is an interface, only the interface itself will be checked.
In accordance with standard meta-annotation semantics, the inheritance hierarchy for interfaces
will not be traversed. See the Javadoc for the
@Inherited
meta-annotation for further details regarding annotation inheritance.
annotationType
- the Class object corresponding to the annotation typeclazz
- the Class object corresponding to the class on which to check for the annotationtrue
if an annotation for the specified annotationType
is present
on the supplied clazz
and is inheritedClass.isAnnotationPresent(Class)
,
isAnnotationDeclaredLocally(Class, Class)
public static boolean isInJavaLangAnnotationPackage(java.lang.annotation.Annotation annotation)
Annotation
is defined in the core JDK
java.lang.annotation
package.annotation
- the annotation to check (never null
)true
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 as-is.
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 forpublic 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 turn Class references into Strings (for
compatibility with AnnotationMetadata
or to preserve them as Class referencespublic static AnnotationAttributes getAnnotationAttributes(java.lang.annotation.Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
AnnotationAttributes
map structure.
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 turn Class references into Strings (for
compatibility with AnnotationMetadata
or to preserve them as Class referencesnestedAnnotationsAsMap
- whether to turn nested Annotation instances into
AnnotationAttributes
maps (for compatibility with
AnnotationMetadata
or to preserve them as
Annotation instancespublic 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 foundgetValue(Annotation, String)
public static java.lang.Object getValue(java.lang.annotation.Annotation annotation, java.lang.String attributeName)
annotation
- the annotation instance from which to retrieve the valueattributeName
- the name of the attribute value to retrievenull
if not foundgetValue(Annotation)
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)
public static java.lang.Object getDefaultValue(java.lang.annotation.Annotation annotation, 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)
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)
public static java.lang.Object getDefaultValue(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, 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)