Подтвердить что ты не робот

Найти аннотацию в 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 !
  //
}
4b9b3361

Ответ 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 !
}