I'm trying to find methods in a Spring RestController that are annotated with a given annotation. In order to see what annotations exist on methods for that RestController, I've done the following:
Map<String, Object> beans = appContext.getBeansWithAnnotation(RestController.class);
for (Map.Entry<String, Object> entry : beans.entrySet()) {
Method[] allMethods = entry.getValue().getClass().getDeclaredMethods();
for(Method method : allMethods) {
LOG.debug("Method: " + method.getName());
Annotation[] annotations = method.getDeclaredAnnotations();
for(Annotation annotation : annotations) {
LOG.debug("Annotation: " + annotation);
}
}
}
The problem is that I'm not seeing any annotations at all, despite the fact that I know I have at least one that is annotated with @Retention(RetentionPolicy.RUNTIME)
. Any ideas? Is CGLIB a factor here? (Being a Controller, the methods in question are bieing proxied using CGBLIB).
Due to the @PreAuthorize
annotation you don't get the actual class but a proxied instance of that class. As annotations aren't inherited (by design in the language) you won't see them.
I suggest to do 2 things, first use the AopProxyUtils.ultimateTargetClass
to get the actual class of the bean and second use the AnnotationUtils
to get the annotation from the class.
Map<String, Object> beans = appContext.getBeansWithAnnotation(RestController.class);
for (Map.Entry<String, Object> entry : beans.entrySet()) {
Class clazz = AopProxyUtils. AopProxyUtils.ultimateTargetClass(entry.getValue());
ReflectionUtils.doWithMethods(clazz, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Annotation[] annotations = AnnotationUtils.getAnnotations(method);
for(Annotation annotation : annotations) {
LOG.debug("Annotation: " + annotation);
}
}
});
}
Something like that should do the trick, also some cleanup using the Spring provided utility classes.