@@ -57,8 +57,8 @@ public abstract class MetaAnnotationUtils {
57
57
58
58
/**
59
59
* Find the {@link AnnotationDescriptor} for the supplied {@code annotationType}
60
- * on the supplied {@link Class}, traversing its annotations and superclasses
61
- * if no annotation can be found on the given class itself.
60
+ * on the supplied {@link Class}, traversing its annotations, interfaces, and
61
+ * superclasses if no annotation can be found on the given class itself.
62
62
* <p>This method explicitly handles class-level annotations which are not
63
63
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
64
64
* well as meta-annotations</em>.
@@ -67,14 +67,12 @@ public abstract class MetaAnnotationUtils {
67
67
* <li>Search for the annotation on the given class and return a corresponding
68
68
* {@code AnnotationDescriptor} if found.
69
69
* <li>Recursively search through all annotations that the given class declares.
70
+ * <li>Recursively search through all interfaces implemented by the given class.
70
71
* <li>Recursively search through the superclass hierarchy of the given class.
71
72
* </ol>
72
73
* <p>In this context, the term <em>recursively</em> means that the search
73
- * process continues by returning to step #1 with the current annotation or
74
- * superclass as the class to look for annotations on.
75
- * <p>If the supplied {@code clazz} is an interface, only the interface
76
- * itself will be checked; the inheritance hierarchy for interfaces will not
77
- * be traversed.
74
+ * process continues by returning to step #1 with the current annotation,
75
+ * interface, or superclass as the class to look for annotations on.
78
76
* @param clazz the class to look for annotations on
79
77
* @param annotationType the type of annotation to look for
80
78
* @return the corresponding annotation descriptor if the annotation was found;
@@ -123,6 +121,15 @@ private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDesc
123
121
}
124
122
}
125
123
124
+ // Declared on interface?
125
+ for (Class <?> ifc : clazz .getInterfaces ()) {
126
+ AnnotationDescriptor <T > descriptor = findAnnotationDescriptor (ifc , visited , annotationType );
127
+ if (descriptor != null ) {
128
+ return new AnnotationDescriptor <T >(clazz , descriptor .getDeclaringClass (),
129
+ descriptor .getComposedAnnotation (), descriptor .getAnnotation ());
130
+ }
131
+ }
132
+
126
133
// Declared on a superclass?
127
134
return findAnnotationDescriptor (clazz .getSuperclass (), visited , annotationType );
128
135
}
@@ -132,8 +139,9 @@ private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDesc
132
139
* in the inheritance hierarchy of the specified {@code clazz} (including
133
140
* the specified {@code clazz} itself) which declares at least one of the
134
141
* specified {@code annotationTypes}.
135
- * <p>This method traverses the annotations and superclasses of the specified
136
- * {@code clazz} if no annotation can be found on the given class itself.
142
+ * <p>This method traverses the annotations, interfaces, and superclasses
143
+ * of the specified {@code clazz} if no annotation can be found on the given
144
+ * class itself.
137
145
* <p>This method explicitly handles class-level annotations which are not
138
146
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
139
147
* well as meta-annotations</em>.
@@ -143,14 +151,12 @@ private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDesc
143
151
* the given class and return a corresponding {@code UntypedAnnotationDescriptor}
144
152
* if found.
145
153
* <li>Recursively search through all annotations that the given class declares.
154
+ * <li>Recursively search through all interfaces implemented by the given class.
146
155
* <li>Recursively search through the superclass hierarchy of the given class.
147
156
* </ol>
148
157
* <p>In this context, the term <em>recursively</em> means that the search
149
- * process continues by returning to step #1 with the current annotation or
150
- * superclass as the class to look for annotations on.
151
- * <p>If the supplied {@code clazz} is an interface, only the interface
152
- * itself will be checked; the inheritance hierarchy for interfaces will not
153
- * be traversed.
158
+ * process continues by returning to step #1 with the current annotation,
159
+ * interface, or superclass as the class to look for annotations on.
154
160
* @param clazz the class to look for annotations on
155
161
* @param annotationTypes the types of annotations to look for
156
162
* @return the corresponding annotation descriptor if one of the annotations
@@ -203,6 +209,15 @@ private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Clas
203
209
}
204
210
}
205
211
212
+ // Declared on interface?
213
+ for (Class <?> ifc : clazz .getInterfaces ()) {
214
+ UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes (ifc , visited , annotationTypes );
215
+ if (descriptor != null ) {
216
+ return new UntypedAnnotationDescriptor (clazz , descriptor .getDeclaringClass (),
217
+ descriptor .getComposedAnnotation (), descriptor .getAnnotation ());
218
+ }
219
+ }
220
+
206
221
// Declared on a superclass?
207
222
return findAnnotationDescriptorForTypes (clazz .getSuperclass (), visited , annotationTypes );
208
223
}
0 commit comments