开发者

Find annotation in Spring proxy bean

开发者 https://www.devze.com 2023-03-11 16:06 出处:网络
I have created my own annotation for classes: @MyAnnotation, and have annotated two classes with it. I have also annotated a few methods in these classes with Spring\'s @Transactional. According to t

I have created my own annotation for classes: @MyAnnotation, and have annotated two classes with it.

I have also annotated a few methods in these classes with Spring's @Transactional. According to the Spring documentation for Transaction Management, the bean factory actually wraps my class into a proxy.

Last, I use the following code to retrieve the annotated beans.

  1. Method getBeansWithAnnotation correctly returns my declared beans. Good.
  2. The class of the bean is actually a proxy class generated by Spring. Good, this means the @Transactional attribute is found and works.
  3. Method findAnnotation does not find MyAnnotation in the bean. Bad. I wish I could read this annotation from the actual classes or proxies seamlessly.

If a bean is a proxy, how can I find the annotations on the actual class ?

What should I be using instead of AnnotationUtils.findAnnotation() for the desired resu开发者_StackOverflow社区lt ?

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 !
  //
}


You can find the real class of the proxied bean by calling AopProxyUtils.ultimateTargetClass.

Determine the ultimate target class of the given bean instance, traversing not only a top-level proxy but any number of nested proxies as well - as long as possible without side effects, that is, just for singleton targets.


The solution is not to work on the bean itself, but to ask the application context instead.

Use method 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 !
}
0

精彩评论

暂无评论...
验证码 换一张
取 消