org.springframework.core.annotation
Class AnnotationUtils

java.lang.Object
  extended by org.springframework.core.annotation.AnnotationUtils

public abstract class AnnotationUtils
extends java.lang.Object

General utility methods for working with annotations, handling bridge methods (which the compiler generates for generic declarations) as well as super methods (for optional "annotation inheritance"). Note that none of this is 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 lookup on the given class level only (getAnnotation(Method, Class)) and lookup in the entire inheritance hierarchy of the given method (findAnnotation(Method, Class)).

Since:
2.0
Author:
Rob Harrop, Juergen Hoeller, Sam Brannen, Mark Fisher
See Also:
AccessibleObject.getAnnotations(), Method.getAnnotation(Class)

Field Summary
private static java.util.Map<java.lang.Class,java.lang.Boolean> annotatedInterfaceCache
           
(package private) static java.lang.String VALUE
          The attribute name for annotations with a single element
 
Constructor Summary
AnnotationUtils()
           
 
Method Summary
static
<A extends java.lang.annotation.Annotation>
A
findAnnotation(java.lang.Class<?> clazz, java.lang.Class<A> annotationType)
          Find a single Annotation of annotationType from the supplied Class, traversing its interfaces and superclasses if no annotation can be found on the given class itself.
static
<A extends java.lang.annotation.Annotation>
A
findAnnotation(java.lang.reflect.Method method, java.lang.Class<A> annotationType)
          Get a single Annotation of annotationType from the supplied Method, traversing its super methods 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
<A extends java.lang.annotation.Annotation>
A
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 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 Annotation 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 Annotation attribute, given the annotation type.
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 Annotation 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).
private static boolean isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface)
           
private static
<A extends java.lang.annotation.Annotation>
A
searchOnInterfaces(java.lang.reflect.Method method, java.lang.Class<A> annotationType, java.lang.Class[] ifcs)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

VALUE

static final java.lang.String VALUE
The attribute name for annotations with a single element

See Also:
Constant Field Values

annotatedInterfaceCache

private static final java.util.Map<java.lang.Class,java.lang.Boolean> annotatedInterfaceCache
Constructor Detail

AnnotationUtils

public AnnotationUtils()
Method Detail

getAnnotations

public static java.lang.annotation.Annotation[] getAnnotations(java.lang.reflect.Method method)
Get all Annotations from the supplied Method.

Correctly handles bridge Methods generated by the compiler.

Parameters:
method - the method to look for annotations on
Returns:
the annotations found
See Also:
BridgeMethodResolver.findBridgedMethod(Method)

getAnnotation

public static <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.reflect.Method method,
                                                                          java.lang.Class<A> annotationType)
Get a single Annotation of annotationType from the supplied Method.

Correctly handles bridge Methods generated by the compiler.

Parameters:
method - the method to look for annotations on
annotationType - the annotation class to look for
Returns:
the annotations found
See Also:
BridgeMethodResolver.findBridgedMethod(Method)

findAnnotation

public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.reflect.Method method,
                                                                           java.lang.Class<A> annotationType)
Get a single Annotation of annotationType from the supplied Method, traversing its super methods 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.

Parameters:
method - the method to look for annotations on
annotationType - the annotation class to look for
Returns:
the annotation found, or null if none found

searchOnInterfaces

private static <A extends java.lang.annotation.Annotation> A searchOnInterfaces(java.lang.reflect.Method method,
                                                                                java.lang.Class<A> annotationType,
                                                                                java.lang.Class[] ifcs)

isInterfaceWithAnnotatedMethods

private static boolean isInterfaceWithAnnotatedMethods(java.lang.Class<?> iface)

findAnnotation

public static <A extends java.lang.annotation.Annotation> A findAnnotation(java.lang.Class<?> clazz,
                                                                           java.lang.Class<A> annotationType)
Find a single Annotation of annotationType from the supplied Class, traversing its interfaces and superclasses 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 annotations on interfaces.

The algorithm operates as follows: Searches for an annotation on the given class and returns it if found. Else searches all interfaces that the given class declares, returning the annotation from the first matching candidate, if any. Else proceeds with introspection of the superclass of the given class, checking the superclass itself; if no annotation found there, proceeds with the interfaces that the superclass declares. Recursing up through the entire superclass hierarchy if no match is found.

Parameters:
clazz - the class to look for annotations on
annotationType - the annotation class to look for
Returns:
the annotation found, or null if none found

findAnnotationDeclaringClass

public 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. 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.

Parameters:
annotationType - the Class object corresponding to the annotation type
clazz - the Class object corresponding to the class on which to check for the annotation, or null
Returns:
the first Class in the inheritance hierarchy of the specified clazz which declares an annotation for the specified annotationType, or null if not found
See Also:
Class.isAnnotationPresent(Class), Class.getDeclaredAnnotations()

isAnnotationDeclaredLocally

public 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. 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.

Parameters:
annotationType - the Class object corresponding to the annotation type
clazz - the Class object corresponding to the class on which to check for the annotation
Returns:
true if an annotation for the specified annotationType is declared locally on the supplied clazz
See Also:
Class.getDeclaredAnnotations(), isAnnotationInherited(Class, Class)

isAnnotationInherited

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

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.

Parameters:
annotationType - the Class object corresponding to the annotation type
clazz - the Class object corresponding to the class on which to check for the annotation
Returns:
true if an annotation for the specified annotationType is present on the supplied clazz and is inherited
See Also:
Class.isAnnotationPresent(Class), isAnnotationDeclaredLocally(Class, Class)

getAnnotationAttributes

public 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.

Parameters:
annotation - the annotation to retrieve the attributes for
Returns:
the Map of annotation attributes, with attribute names as keys and corresponding attribute values as values

getAnnotationAttributes

public 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.

Parameters:
annotation - the annotation to retrieve the attributes for
classValuesAsString - whether to turn Class references into Strings (for compatibility with AnnotationMetadata or to preserve them as Class references
Returns:
the Map of annotation attributes, with attribute names as keys and corresponding attribute values as values

getValue

public 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.

Parameters:
annotation - the annotation instance from which to retrieve the value
Returns:
the attribute value, or null if not found
See Also:
getValue(Annotation, String)

getValue

public static java.lang.Object getValue(java.lang.annotation.Annotation annotation,
                                        java.lang.String attributeName)
Retrieve the value of a named Annotation attribute, given an annotation instance.

Parameters:
annotation - the annotation instance from which to retrieve the value
attributeName - the name of the attribute value to retrieve
Returns:
the attribute value, or null if not found
See Also:
getValue(Annotation)

getDefaultValue

public 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.

Parameters:
annotation - the annotation instance from which to retrieve the default value
Returns:
the default value, or null if not found
See Also:
getDefaultValue(Annotation, String)

getDefaultValue

public static java.lang.Object getDefaultValue(java.lang.annotation.Annotation annotation,
                                               java.lang.String attributeName)
Retrieve the default value of a named Annotation attribute, given an annotation instance.

Parameters:
annotation - the annotation instance from which to retrieve the default value
attributeName - the name of the attribute value to retrieve
Returns:
the default value of the named attribute, or null if not found
See Also:
getDefaultValue(Class, String)

getDefaultValue

public 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.

Parameters:
annotationType - the annotation type for which the default value should be retrieved
Returns:
the default value, or null if not found
See Also:
getDefaultValue(Class, String)

getDefaultValue

public 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 Annotation attribute, given the annotation type.

Parameters:
annotationType - the annotation type for which the default value should be retrieved
attributeName - the name of the attribute value to retrieve.
Returns:
the default value of the named attribute, or null if not found
See Also:
getDefaultValue(Annotation, String)