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.
- Method
getBeansWithAnnotation
correctly returns my declared beans. Good. - The class of the bean is actually a proxy class generated by Spring. Good, this means the
@Transactional
attribute is found and works. - 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 !
}
精彩评论