Не удается увидеть аннотации через отражение, несмотря на то, что RetentionPolicy является RUNTIME - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь найти методы в 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 голосов
/ 05 июня 2018

Из-за аннотации @PreAuthorize вы получаете не фактический класс, а прокси-экземпляр этого класса.Так как аннотации не наследуются (по замыслу на языке), вы их не увидите.

Я предлагаю сделать 2 вещи: во-первых, используйте AopProxyUtils.ultimateTargetClass, чтобы получить фактический класс компонента, а во-вторых, используйте 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.

...