Найти аннотацию в Spring прокси bean
Я создал свою собственную аннотацию для классов: @MyAnnotation
и аннотировал с ней два класса.
Я также аннотировал несколько методов в этих классах с помощью Spring @Transactional
. Согласно Spring документации для управления транзакциями, bean factory фактически переносит мой класс в прокси.
Наконец, я использую следующий код для извлечения аннотированного beans.
- Метод
getBeansWithAnnotation
корректно возвращает объявленный beans. Хорошо.
- Класс bean на самом деле является прокси-классом, сгенерированным Spring. Хорошо, это означает, что атрибут
@Transactional
найден и работает.
- Метод findAnnotation не находит
MyAnnotation
в bean. Плохо. Хотелось бы, чтобы я мог полностью прочитать эту аннотацию из реальных классов или прокси.
Если bean является прокси-сервером, как я могу найти аннотации в действительном классе?
Что я должен использовать вместо AnnotationUtils.findAnnotation()
для желаемого результата?
Map<String,Object> beans = ctx.getBeansWithAnnotation(MyAnnotation.class);
System.out.println(beans.size());
// prints 2. ok !
for (Object bean: services.values()) {
System.out.println(bean.getClass());
// $Proxy
MyAnnotation annotation = AnnotationUtils.findAnnotation(svc.getClass(), MyAnnotation.class);
//
// Problem ! annotation is null !
//
}
Ответы
Ответ 1
Вы можете найти реальный класс проксированного bean, вызвав AopProxyUtils.ultimateTargetClass.
Определить конечный целевой класс данного экземпляра bean, проходящий не только прокси-сервер верхнего уровня, но любое количество вложенных прокси-серверов, а также как можно больше без побочных эффектов, то есть только для синглтона цели.
Ответ 2
Решение не должно работать на самом bean, а вместо этого запрашивать контекст приложения.
Использовать метод ApplicationContext # findAnnotationOnBean (String, Class).
Map<String,Object> beans = ctx.getBeansWithAnnotation(MyAnnotation.class);
System.out.println(beans.size());
// prints 2. ok !
for (Object bean: services.values()) {
System.out.println(bean.getClass());
// $Proxy
/* MyAnnotation annotation = AnnotationUtils.findAnnotation(svc.getClass(), MyAnnotation.class);
// Problem ! annotation is null !
*/
MyAnnotation annotation = ctx.findAnnotationOnBean(beanName, MyAnnotation.class);
// Yay ! Correct !
}