@ -34,16 +34,19 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils ;
import org.springframework.util.ReflectionUtils ;
/ * *
/ * *
* General utility methods for working with annotations , handling bridge methods ( which the compiler
* General utility methods for working with annotations , handling bridge methods
* generates for generic declarations ) as well as super methods ( for optional & quot ; annotation inheritance & quot ; ) .
* ( which the compiler generates for generic declarations ) as well as super methods
* Note that none of this is provided by the JDK ' s introspection facilities themselves .
* ( for optional & quot ; annotation inheritance & quot ; ) . Note that none of this is
* provided by the JDK ' s introspection facilities themselves .
*
*
* < p > As a general rule for runtime - retained annotations ( e . g . for transaction control , authorization or service
* < p > As a general rule for runtime - retained annotations ( e . g . for transaction
* exposure ) , always use the lookup methods on this class ( e . g . , { @link # findAnnotation ( Method , Class ) } , { @link
* control , authorization , or service exposure ) , always use the lookup methods
* # getAnnotation ( Method , Class ) } , and { @link # getAnnotations ( Method ) } ) instead of the plain annotation lookup
* on this class ( e . g . , { @link # findAnnotation ( Method , Class ) } ,
* methods in the JDK . You can still explicitly choose between lookup on the given class level only ( { @link
* { @link # getAnnotation ( Method , Class ) } , and { @link # getAnnotations ( Method ) } )
* # getAnnotation ( Method , Class ) } ) and lookup in the entire inheritance hierarchy of the given method ( { @link
* instead of the plain annotation lookup methods in the JDK . You can still
* # findAnnotation ( Method , Class ) } ) .
* explicitly choose between a < em > get < / em > lookup on the given class level only
* ( { @link # getAnnotation ( Method , Class ) } ) and a < em > find < / em > lookup in the entire
* inheritance hierarchy of the given method ( { @link # findAnnotation ( Method , Class ) } ) .
*
*
* @author Rob Harrop
* @author Rob Harrop
* @author Juergen Hoeller
* @author Juergen Hoeller
@ -165,9 +168,11 @@ public abstract class AnnotationUtils {
}
}
/ * *
/ * *
* Get a single { @link Annotation } of { @code annotationType } from the supplied { @link Method } ,
* Find a single { @link Annotation } of { @code annotationType } from the supplied
* traversing its super methods if no annotation can be found on the given method itself .
* { @link Method } , traversing its super methods ( i . e . , from super classes and
* < p > Annotations on methods are not inherited by default , so we need to handle this explicitly .
* interfaces ) if no annotation can be found on the given method itself .
* < p > Annotations on methods are not inherited by default , so we need to handle
* this explicitly .
* @param method the method to look for annotations on
* @param method the method to look for annotations on
* @param annotationType the annotation class to look for
* @param annotationType the annotation class to look for
* @return the annotation found , or { @code null } if none found
* @return the annotation found , or { @code null } if none found
@ -235,16 +240,23 @@ public abstract class AnnotationUtils {
}
}
/ * *
/ * *
* Find a single { @link Annotation } of { @code annotationType } from the supplied { @link Class } ,
* Find a single { @link Annotation } of { @code annotationType } from the supplied
* traversing its interfaces and superclasses if no annotation can be found on the given class itself .
* { @link Class } , traversing its annotations , interfaces , and superclasses if
* < p > This method explicitly handles class - level annotations which are not declared as
* no annotation can be found on the given class itself .
* { @link java . lang . annotation . Inherited inherited } < i > as well as annotations on interfaces < / i > .
* < p > This method explicitly handles class - level annotations which are not
* < p > The algorithm operates as follows : Searches for an annotation on the given class and returns
* declared as { @link java . lang . annotation . Inherited inherited } < i > as well
* it if found . Else searches all interfaces that the given class declares , returning the annotation
* as meta - annotations and annotations on interfaces < / i > .
* from the first matching candidate , if any . Else proceeds with introspection of the superclass
* < p > The algorithm operates as follows :
* of the given class , checking the superclass itself ; if no annotation found there , proceeds
* < ol >
* with the interfaces that the superclass declares . Recursing up through the entire superclass
* < li > Search for an annotation on the given class and return it if found .
* hierarchy if no match is found .
* < li > Recursively search through all interfaces that the given class
* declares , returning the annotation from the first matching candidate , if any .
* < li > Recursively search through all annotations that the given class
* declares , returning the annotation from the first matching candidate , if any .
* < li > Proceed with introspection of the superclass hierarchy of the given
* class by returning to step # 1 with the superclass as the class to look for
* annotations on .
* < / ol >
* @param clazz the class to look for annotations on
* @param clazz the class to look for annotations on
* @param annotationType the annotation class to look for
* @param annotationType the annotation class to look for
* @return the annotation found , or { @code null } if none found
* @return the annotation found , or { @code null } if none found
@ -301,23 +313,9 @@ public abstract class AnnotationUtils {
if ( clazz = = null | | clazz . equals ( Object . class ) ) {
if ( clazz = = null | | clazz . equals ( Object . class ) ) {
return null ;
return null ;
}
}
// Declared locally?
if ( isAnnotationDeclaredLocally ( annotationType , clazz ) ) {
if ( isAnnotationDeclaredLocally ( annotationType , clazz ) ) {
return clazz ;
return clazz ;
}
}
// Declared on a stereotype annotation (i.e., as a meta-annotation)?
if ( ! Annotation . class . isAssignableFrom ( clazz ) ) {
for ( Annotation stereotype : clazz . getAnnotations ( ) ) {
Class < ? > declaringClass = findAnnotationDeclaringClass ( annotationType , stereotype . annotationType ( ) ) ;
if ( declaringClass ! = null ) {
return declaringClass ;
}
}
}
// Declared on a superclass?
return findAnnotationDeclaringClass ( annotationType , clazz . getSuperclass ( ) ) ;
return findAnnotationDeclaringClass ( annotationType , clazz . getSuperclass ( ) ) ;
}
}