summaryrefslogtreecommitdiff
path: root/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java')
-rw-r--r--spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java43
1 files changed, 29 insertions, 14 deletions
diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java
index 913986a4..9c203d74 100644
--- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java
@@ -57,8 +57,8 @@ public abstract class MetaAnnotationUtils {
/**
* Find the {@link AnnotationDescriptor} for the supplied {@code annotationType}
- * on the supplied {@link Class}, traversing its annotations and superclasses
- * if no annotation can be found on the given class itself.
+ * on the supplied {@link Class}, traversing its annotations, interfaces, and
+ * superclasses if no annotation can be found on the given class itself.
* <p>This method explicitly handles class-level annotations which are not
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
* well as meta-annotations</em>.
@@ -67,14 +67,12 @@ public abstract class MetaAnnotationUtils {
* <li>Search for the annotation on the given class and return a corresponding
* {@code AnnotationDescriptor} if found.
* <li>Recursively search through all annotations that the given class declares.
+ * <li>Recursively search through all interfaces implemented by the given class.
* <li>Recursively search through the superclass hierarchy of the given class.
* </ol>
* <p>In this context, the term <em>recursively</em> means that the search
- * process continues by returning to step #1 with the current annotation or
- * superclass as the class to look for annotations on.
- * <p>If the supplied {@code clazz} is an interface, only the interface
- * itself will be checked; the inheritance hierarchy for interfaces will not
- * be traversed.
+ * process continues by returning to step #1 with the current annotation,
+ * interface, or superclass as the class to look for annotations on.
* @param clazz the class to look for annotations on
* @param annotationType the type of annotation to look for
* @return the corresponding annotation descriptor if the annotation was found;
@@ -123,6 +121,15 @@ public abstract class MetaAnnotationUtils {
}
}
+ // Declared on interface?
+ for (Class<?> ifc : clazz.getInterfaces()) {
+ AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(ifc, visited, annotationType);
+ if (descriptor != null) {
+ return new AnnotationDescriptor<T>(clazz, descriptor.getDeclaringClass(),
+ descriptor.getComposedAnnotation(), descriptor.getAnnotation());
+ }
+ }
+
// Declared on a superclass?
return findAnnotationDescriptor(clazz.getSuperclass(), visited, annotationType);
}
@@ -132,8 +139,9 @@ public abstract class MetaAnnotationUtils {
* in the inheritance hierarchy of the specified {@code clazz} (including
* the specified {@code clazz} itself) which declares at least one of the
* specified {@code annotationTypes}.
- * <p>This method traverses the annotations and superclasses of the specified
- * {@code clazz} if no annotation can be found on the given class itself.
+ * <p>This method traverses the annotations, interfaces, and superclasses
+ * of the specified {@code clazz} if no annotation can be found on the given
+ * class itself.
* <p>This method explicitly handles class-level annotations which are not
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
* well as meta-annotations</em>.
@@ -143,14 +151,12 @@ public abstract class MetaAnnotationUtils {
* the given class and return a corresponding {@code UntypedAnnotationDescriptor}
* if found.
* <li>Recursively search through all annotations that the given class declares.
+ * <li>Recursively search through all interfaces implemented by the given class.
* <li>Recursively search through the superclass hierarchy of the given class.
* </ol>
* <p>In this context, the term <em>recursively</em> means that the search
- * process continues by returning to step #1 with the current annotation or
- * superclass as the class to look for annotations on.
- * <p>If the supplied {@code clazz} is an interface, only the interface
- * itself will be checked; the inheritance hierarchy for interfaces will not
- * be traversed.
+ * process continues by returning to step #1 with the current annotation,
+ * interface, or superclass as the class to look for annotations on.
* @param clazz the class to look for annotations on
* @param annotationTypes the types of annotations to look for
* @return the corresponding annotation descriptor if one of the annotations
@@ -203,6 +209,15 @@ public abstract class MetaAnnotationUtils {
}
}
+ // Declared on interface?
+ for (Class<?> ifc : clazz.getInterfaces()) {
+ UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, visited, annotationTypes);
+ if (descriptor != null) {
+ return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
+ descriptor.getComposedAnnotation(), descriptor.getAnnotation());
+ }
+ }
+
// Declared on a superclass?
return findAnnotationDescriptorForTypes(clazz.getSuperclass(), visited, annotationTypes);
}