Support arbitrary levels of meta-annotations in TypeDescriptor
Prior to this commit, the `getAnnotation()` method in `TypeDescriptor` only supported a single level of meta-annotations. In other words, the annotation hierarchy would not be exhaustively searched. This commit provides support for arbitrary levels of meta-annotations in `TypeDescriptor` by delegating to `AnnotationUtils.findAnnotation()` within `TypeDescriptor.getAnnotation()`. Issue: SPR-12793
This commit is contained in:
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -237,6 +238,8 @@ public class TypeDescriptor implements Serializable {
|
||||
|
||||
/**
|
||||
* Determine if this type descriptor has the specified annotation.
|
||||
* <p>As of Spring Framework 4.2, this method supports arbitrary levels
|
||||
* of meta-annotations.
|
||||
* @param annotationType the annotation type
|
||||
* @return <tt>true</tt> if the annotation is present
|
||||
*/
|
||||
@@ -245,19 +248,27 @@ public class TypeDescriptor implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the annotation associated with this type descriptor of the specified type.
|
||||
* Obtain the annotation of the specified {@code annotationType} that is
|
||||
* on this type descriptor.
|
||||
* <p>As of Spring Framework 4.2, this method supports arbitrary levels
|
||||
* of meta-annotations.
|
||||
* @param annotationType the annotation type
|
||||
* @return the annotation, or {@code null} if no such annotation exists on this type descriptor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
|
||||
// Search in annotations that are "present" (i.e., locally declared or inherited)
|
||||
//
|
||||
// NOTE: this unfortunately favors inherited annotations over locally declared composed annotations.
|
||||
for (Annotation annotation : getAnnotations()) {
|
||||
if (annotation.annotationType().equals(annotationType)) {
|
||||
return (T) annotation;
|
||||
}
|
||||
}
|
||||
for (Annotation metaAnn : getAnnotations()) {
|
||||
T ann = metaAnn.annotationType().getAnnotation(annotationType);
|
||||
|
||||
// Search in annotation hierarchy
|
||||
for (Annotation composedAnnotation : getAnnotations()) {
|
||||
T ann = AnnotationUtils.findAnnotation(composedAnnotation.annotationType(), annotationType);
|
||||
if (ann != null) {
|
||||
return ann;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user