@ -26,19 +26,16 @@ import org.springframework.core.BridgeMethodResolver;
@@ -26,19 +26,16 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert ;
/ * *
* General utility methods for working with annotations , handling bridge methods
* ( which the compiler generates for generic declarations ) as well as super
* methods ( for optional & quot ; annotation inheritance & quot ; ) . Note that none of
* this is provided by the JDK ' s introspection facilities themselves .
* General utility methods for working with annotations , handling bridge methods ( which the compiler
* generates for generic declarations ) as well as super methods ( 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 exposure ) , always use the lookup methods on
* this class ( e . g . , { @link # findAnnotation ( Method , Class ) } ,
* { @link # getAnnotation ( Method , Class ) } , and { @link # 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
* ( { @link # getAnnotation ( Method , Class ) } ) and lookup in the entire inheritance
* hierarchy of the given method ( { @link # findAnnotation ( Method , Class ) } ) .
* < p > 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 . , { @link # findAnnotation ( Method , Class ) } , { @link
* # getAnnotation ( Method , Class ) } , and { @link # 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 ( { @link
* # getAnnotation ( Method , Class ) } ) and lookup in the entire inheritance hierarchy of the given method ( { @link
* # findAnnotation ( Method , Class ) } ) .
*
* @author Rob Harrop
* @author Juergen Hoeller
@ -51,8 +48,7 @@ import org.springframework.util.Assert;
@@ -51,8 +48,7 @@ import org.springframework.util.Assert;
public abstract class AnnotationUtils {
/** The attribute name for annotations with a single element */
static final String VALUE = "value" ;
static final String VALUE = "value" ;
/ * *
* Get all { @link Annotation Annotations } from the supplied { @link Method } .
@ -66,8 +62,7 @@ public abstract class AnnotationUtils {
@@ -66,8 +62,7 @@ public abstract class AnnotationUtils {
}
/ * *
* Get a single { @link Annotation } of < code > annotationType < / code > from the
* supplied { @link Method } .
* Get a single { @link Annotation } of < code > annotationType < / code > from the supplied { @link Method } .
* < p > Correctly handles bridge { @link Method Methods } generated by the compiler .
* @param method the method to look for annotations on
* @param annotationType the annotation class to look for
@ -89,11 +84,9 @@ public abstract class AnnotationUtils {
@@ -89,11 +84,9 @@ public abstract class AnnotationUtils {
}
/ * *
* Get a single { @link Annotation } of < code > annotationType < / code > from the
* supplied { @link Method } , traversing its super methods 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 .
* Get a single { @link Annotation } of < code > annotationType < / code > from the supplied { @link Method } ,
* traversing its super methods 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 annotationType the annotation class to look for
* @return the annotation found , or < code > null < / code > if none found
@ -101,8 +94,8 @@ public abstract class AnnotationUtils {
@@ -101,8 +94,8 @@ public abstract class AnnotationUtils {
public static < A extends Annotation > A findAnnotation ( Method method , Class < A > annotationType ) {
A annotation = getAnnotation ( method , annotationType ) ;
Class < ? > cl = method . getDeclaringClass ( ) ;
if ( annotation = = null ) {
annotation = searchForAnnotation OnInterfaces ( method , annotationType , cl . getInterfaces ( ) ) ;
if ( annotation = = null ) {
annotation = searchOnInterfaces ( method , annotationType , cl . getInterfaces ( ) ) ;
}
while ( annotation = = null ) {
cl = cl . getSuperclass ( ) ;
@ -112,8 +105,8 @@ public abstract class AnnotationUtils {
@@ -112,8 +105,8 @@ public abstract class AnnotationUtils {
try {
Method equivalentMethod = cl . getDeclaredMethod ( method . getName ( ) , method . getParameterTypes ( ) ) ;
annotation = getAnnotation ( equivalentMethod , annotationType ) ;
if ( annotation = = null ) {
annotation = searchForAnnotation OnInterfaces ( method , annotationType , cl . getInterfaces ( ) ) ;
if ( annotation = = null ) {
annotation = searchOnInterfaces ( method , annotationType , cl . getInterfaces ( ) ) ;
}
}
catch ( NoSuchMethodException ex ) {
@ -123,9 +116,9 @@ public abstract class AnnotationUtils {
@@ -123,9 +116,9 @@ public abstract class AnnotationUtils {
return annotation ;
}
private static < A extends Annotation > A searchForAnnotation OnInterfaces ( Method method , Class < A > annotationType , Class [ ] ifa ce s ) {
private static < A extends Annotation > A searchOnInterfaces ( Method method , Class < A > annotationType , Class [ ] ifcs ) {
A annotation = null ;
for ( Class < ? > iface : ifa ce s ) {
for ( Class < ? > iface : ifcs ) {
Method equivalentMethod = null ;
try {
equivalentMethod = iface . getDeclaredMethod ( method . getName ( ) , method . getParameterTypes ( ) ) ;
@ -142,19 +135,14 @@ public abstract class AnnotationUtils {
@@ -142,19 +135,14 @@ public abstract class AnnotationUtils {
}
/ * *
* Find a single { @link Annotation } of < code > annotationType < / code > from the
* supplied { @link Class } , traversing its interfaces and super classes
* if no annotation can be found on the given class itself .
* < p > This method explicitly handles class - level annotations which are
* not declared as { @link java . lang . annotation . Inherited inherited }
* < i > as well as annotations on interfaces < / i > .
* < p > 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 .
* Find a single { @link Annotation } of < code > annotationType < / code > from the supplied { @link Class } , traversing its
* interfaces and super classes if no annotation can be found on the given class itself . < p > This method explicitly
* handles class - level annotations which are not declared as { @link java . lang . annotation . Inherited inherited } < i > as
* well as annotations on interfaces < / i > . < p > 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 .
* @param clazz the class to look for annotations on
* @param annotationType the annotation class to look for
* @return the annotation found , or < code > null < / code > if none found
@ -187,24 +175,18 @@ public abstract class AnnotationUtils {
@@ -187,24 +175,18 @@ public abstract class AnnotationUtils {
}
/ * *
* Find the first { @link Class } in the inheritance hierarchy of the
* specified < code > clazz < / code > ( including the specified
* < code > clazz < / code > itself ) which declares an annotation for the
* specified < code > annotationType < / code > , or < code > null < / code > if not
* found . If the supplied < code > clazz < / code > is < code > null < / code > ,
* < code > null < / code > will be returned .
* < p > If the supplied < code > clazz < / code > is an interface , only the interface
* itself will be checked ; the inheritance hierarchy for interfaces will not
* be traversed .
* < p > The standard { @link Class } API does not provide a mechanism for
* determining which class in an inheritance hierarchy actually declares an
* { @link Annotation } , so we need to handle this explicitly .
* Find the first { @link Class } in the inheritance hierarchy of the specified < code > clazz < / code > ( including the
* specified < code > clazz < / code > itself ) which declares an annotation for the specified < code > annotationType < / code > , or
* < code > null < / code > if not found . If the supplied < code > clazz < / code > is < code > null < / code > , < code > null < / code > will be
* returned . < p > If the supplied < code > clazz < / code > is an interface , only the interface itself will be checked ; the
* inheritance hierarchy for interfaces will not be traversed . < p > The standard { @link Class } API does not provide a
* mechanism for determining which class in an inheritance hierarchy actually declares an { @link Annotation } , so we
* need to handle this explicitly .
* @param annotationType the Class object corresponding to the annotation type
* @param clazz the Class object corresponding to the class on which to
* check for the annotation , or < code > null < / code > .
* @return the first { @link Class } in the inheritance hierarchy of the
* specified < code > clazz < / code > which declares an annotation for the specified
* < code > annotationType < / code > , or < code > null < / code > if not found .
* @param clazz the Class object corresponding to the class on which to check for the annotation , or
* < code > null < / code > .
* @return the first { @link Class } in the inheritance hierarchy of the specified < code > clazz < / code > which
* declares an annotation for the specified < code > annotationType < / code > , or < code > null < / code > if not found .
* @see Class # isAnnotationPresent ( Class )
* @see Class # getDeclaredAnnotations ( )
* /
@ -213,23 +195,21 @@ public abstract class AnnotationUtils {
@@ -213,23 +195,21 @@ public abstract class AnnotationUtils {
if ( clazz = = null | | clazz . equals ( Object . class ) ) {
return null ;
}
return ( isAnnotationDeclaredLocally ( annotationType , clazz ) ) ?
clazz : findAnnotationDeclaringClass ( annotationType , clazz . getSuperclass ( ) ) ;
return ( isAnnotationDeclaredLocally ( annotationType , clazz ) ) ? clazz :
findAnnotationDeclaringClass ( annotationType , clazz . getSuperclass ( ) ) ;
}
/ * *
* Determine whether an annotation for the specified < code > annotationType < / code >
* is declared locally on the supplied < code > clazz < / code > .
* The supplied { @link Class } object may represent any type .
* < p > Note : This method does < strong > not < / strong > determine if the annotation
* is { @link java . lang . annotation . Inherited inherited } . For greater clarity
* regarding inherited annotations , consider using
* { @link # isAnnotationInherited ( Class , Class ) } instead .
* Determine whether an annotation for the specified < code > annotationType < / code > is
* declared locally on the supplied < code > clazz < / code > . The supplied { @link Class }
* may represent any type .
* < p > Note : This method does < strong > not < / strong > determine if the annotation is
* { @link java . lang . annotation . Inherited inherited } . For greater clarity regarding inherited
* annotations , consider using { @link # isAnnotationInherited ( Class , Class ) } instead .
* @param annotationType the Class object corresponding to the annotation type
* @param clazz the Class object corresponding to the class on which to
* check for the annotation
* @return < code > true < / code > if an annotation for the specified
* < code > annotationType < / code > is declared locally on the supplied < code > clazz < / code >
* @param clazz the Class object corresponding to the class on which to check for the annotation
* @return < code > true < / code > if an annotation for the specified < code > annotationType < / code >
* is declared locally on the supplied < code > clazz < / code >
* @see Class # getDeclaredAnnotations ( )
* @see # isAnnotationInherited ( Class , Class )
* /
@ -247,22 +227,17 @@ public abstract class AnnotationUtils {
@@ -247,22 +227,17 @@ public abstract class AnnotationUtils {
}
/ * *
* Determine whether an annotation for the specified < code > annotationType < / code >
* is present on the supplied < code > clazz < / code > and is
* { @link java . lang . annotation . Inherited inherited }
* ( i . e . , not declared locally for the class ) .
* < p > If the supplied < code > clazz < / code > is an interface , only the interface
* itself will be checked . In accord with standard meta - annotation
* semantics , the inheritance hierarchy for interfaces will not be
* traversed . See the { @link java . lang . annotation . Inherited JavaDoc } for the
* & # 064 ; Inherited meta - annotation for further details regarding annotation
* inheritance .
* Determine whether an annotation for the specified < code > annotationType < / code > is present
* on the supplied < code > clazz < / code > and is { @link java . lang . annotation . Inherited inherited }
* i . e . , not declared locally for the class ) .
* < p > If the supplied < code > clazz < / code > 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 { @link java . lang . annotation . Inherited JavaDoc } for the
* & # 064 ; Inherited meta - annotation for further details regarding annotation inheritance .
* @param annotationType the Class object corresponding to the annotation type
* @param clazz the Class object corresponding to the class on which to
* check for the annotation
* @return < code > true < / code > if an annotation for the specified
* < code > annotationType < / code > is present on the supplied < code > clazz < / code >
* and is { @link java . lang . annotation . Inherited inherited }
* @param clazz the Class object corresponding to the class on which to check for the annotation
* @return < code > true < / code > if an annotation for the specified < code > annotationType < / code > is present
* on the supplied < code > clazz < / code > and is { @link java . lang . annotation . Inherited inherited }
* @see Class # isAnnotationPresent ( Class )
* @see # isAnnotationDeclaredLocally ( Class , Class )
* /
@ -273,11 +248,10 @@ public abstract class AnnotationUtils {
@@ -273,11 +248,10 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the given annotation ' s attributes as a Map ,
* preserving all attribute types as - is .
* Retrieve the given annotation ' s attributes as a Map , preserving all attribute types as - is .
* @param annotation the annotation to retrieve the attributes for
* @return the Map of annotation attributes , with attribute names as keys
* and corresponding attribute values as values
* @return the Map of annotation attributes , with attribute names as keys and
* corresponding attribute values as values
* /
public static Map < String , Object > getAnnotationAttributes ( Annotation annotation ) {
return getAnnotationAttributes ( annotation , false ) ;
@ -286,11 +260,10 @@ public abstract class AnnotationUtils {
@@ -286,11 +260,10 @@ public abstract class AnnotationUtils {
/ * *
* Retrieve the given annotation ' s attributes as a Map .
* @param annotation the annotation to retrieve the attributes for
* @param classValuesAsString whether to turn Class references into Strings
* ( for compatibility with { @link org . springframework . core . type . AnnotationMetadata }
* or to preserve them as Class references
* @return the Map of annotation attributes , with attribute names as keys
* and corresponding attribute values as values
* @param classValuesAsString whether to turn Class references into Strings ( for compatibility with
* { @link org . springframework . core . type . AnnotationMetadata } or to preserve them as Class references
* @return the Map of annotation attributes , with attribute names as keys and
* corresponding attribute values as values
* /
public static Map < String , Object > getAnnotationAttributes ( Annotation annotation , boolean classValuesAsString ) {
Map < String , Object > attrs = new HashMap < String , Object > ( ) ;
@ -323,8 +296,8 @@ public abstract class AnnotationUtils {
@@ -323,8 +296,8 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > value < / em > of the < code > & quot ; value & quot ; < / code >
* attribute of a single - element Annotation , given an annotation instance .
* Retrieve the < em > value < / em > of the < code > & quot ; value & quot ; < / code > attribute of a
* single - element Annotation , given an annotation instance .
* @param annotation the annotation instance from which to retrieve the value
* @return the attribute value , or < code > null < / code > if not found
* @see # getValue ( Annotation , String )
@ -334,12 +307,11 @@ public abstract class AnnotationUtils {
@@ -334,12 +307,11 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > value < / em > of a named Annotation attribute , given an
* annotation instance .
* @see # getValue ( Annotation )
* Retrieve the < em > value < / em > of a named Annotation attribute , given an annotation instance .
* @param annotation the annotation instance from which to retrieve the value
* @param attributeName the name of the attribute value to retrieve
* @return the attribute value , or < code > null < / code > if not found
* @see # getValue ( Annotation )
* /
public static Object getValue ( Annotation annotation , String attributeName ) {
try {
@ -352,11 +324,9 @@ public abstract class AnnotationUtils {
@@ -352,11 +324,9 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > default value < / em > of the
* < code > & quot ; value & quot ; < / code > attribute of a single - element
* Annotation , given an annotation instance .
* @param annotation the annotation instance from which to retrieve
* the default value
* Retrieve the < em > default value < / em > of the < code > & quot ; value & quot ; < / code > attribute
* of a single - element Annotation , given an annotation instance .
* @param annotation the annotation instance from which to retrieve the default value
* @return the default value , or < code > null < / code > if not found
* @see # getDefaultValue ( Annotation , String )
* /
@ -365,13 +335,10 @@ public abstract class AnnotationUtils {
@@ -365,13 +335,10 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > default value < / em > of a named Annotation attribute ,
* given an annotation instance .
* @param annotation the annotation instance from which to retrieve
* the default value
* Retrieve the < em > default value < / em > of a named Annotation attribute , given an annotation instance .
* @param annotation the annotation instance from which to retrieve the default value
* @param attributeName the name of the attribute value to retrieve
* @return the default value of the named attribute , or < code > null < / code >
* if not found .
* @return the default value of the named attribute , or < code > null < / code > if not found .
* @see # getDefaultValue ( Class , String )
* /
public static Object getDefaultValue ( Annotation annotation , String attributeName ) {
@ -379,11 +346,9 @@ public abstract class AnnotationUtils {
@@ -379,11 +346,9 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > default value < / em > of the
* < code > & quot ; value & quot ; < / code > attribute of a single - element
* Annotation , given the { @link Class annotation type } .
* @param annotationType the < em > annotation type < / em > for which the
* default value should be retrieved
* Retrieve the < em > default value < / em > of the < code > & quot ; value & quot ; < / code > attribute
* of a single - element Annotation , given the { @link Class annotation type } .
* @param annotationType the < em > annotation type < / em > for which the default value should be retrieved
* @return the default value , or < code > null < / code > if not found
* @see # getDefaultValue ( Class , String )
* /
@ -392,13 +357,10 @@ public abstract class AnnotationUtils {
@@ -392,13 +357,10 @@ public abstract class AnnotationUtils {
}
/ * *
* Retrieve the < em > default value < / em > of a named Annotation attribute ,
* given the { @link Class annotation type } .
* @param annotationType the < em > annotation type < / em > for which the
* default value should be retrieved
* Retrieve the < em > default value < / em > of a named Annotation attribute , given the { @link Class annotation type } .
* @param annotationType the < em > annotation type < / em > for which the default value should be retrieved
* @param attributeName the name of the attribute value to retrieve .
* @return the default value of the named attribute , or < code > null < / code >
* if not found
* @return the default value of the named attribute , or < code > null < / code > if not found
* @see # getDefaultValue ( Annotation , String )
* /
public static Object getDefaultValue ( Class < ? extends Annotation > annotationType , String attributeName ) {