尽管RetentionPolicy是RUNTIME,但无法通过反射查看注释

时间:2018-06-05 08:06:47

标签: java spring spring-mvc reflection cglib

我正在尝试在Spring RestController中查找使用给定注释进行注释的方法。为了查看RestController的方法上存在哪些注释,我已经完成了以下操作:

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);
        }
    }
}

问题在于我根本没有看到任何注释,尽管我知道我至少有一个注释@Retention(RetentionPolicy.RUNTIME)。有任何想法吗? CGLIB是这里的一个因素吗? (作为一个控制器,所讨论的方法是使用CGBLIB进行代理)。

1 个答案:

答案 0 :(得分:1)

由于@PreAuthorize注释,您不会获得实际的类,而是该类的代理实例。由于注释没有被继承(通过语言设计),您将无法看到它们。

我建议做两件事,首先使用AopProxyUtils.ultimateTargetClass来获取bean的实际类,然后使用AnnotationUtils来获取类中的注释。

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);
            }
        }
    });
}

这样的事情应该可以解决问题,也可以使用Spring提供的实用程序类进行一些清理。