【问题标题】:Find annotation in Spring proxy bean在 Spring 代理 bean 中查找注解
【发布时间】:2011-09-09 13:39:37
【问题描述】:

我为类创建了自己的注释:@MyAnnotation,并用它注释了两个类。

我还在这些类中使用 Spring 的 @Transactional 注释了一些方法。根据Spring documentation for Transaction Management的说法,bean factory其实是把我的类包装成代理了。

最后,我使用以下代码来检索带注释的 bean。

  1. 方法getBeansWithAnnotation 正确返回我声明的bean。 很好。
  2. bean的类实际上是Spring生成的代理类。 很好,这意味着@Transactional 属性已找到并且有效。
  3. 方法 findAnnotation 在 bean 中找不到 MyAnnotation不好。我希望我能从实际的类或代理中无缝地读取此注释。

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

【问题讨论】:

  • 它是什么样的代理? (JDK 与 cglib 等)。
  • 我猜 Spring 默认使用 JDK 代理。
  • 似乎这将是对框架的一个很好的增强。自从您很久以前发帖以来,您是否对此进行过调查?

标签: spring


【解决方案1】:

你可以通过调用AopProxyUtils.ultimateTargetClass找到代理bean的真实类。

确定 给定 bean 实例的最终目标类,不遍历 只是一个顶级代理,但还有任意数量的嵌套代理 - 以及 尽可能长的没有副作用,也就是只针对singleton 目标。

【讨论】:

    【解决方案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 !
    }
    

    【讨论】:

    • 如何找到具有给定注释的方法
    • 这似乎(不确定地)仅在部分时间有效,即使我在同一个平台和 JRE 上多次运行同一个捆绑的应用程序 JAR
    猜你喜欢
    • 2014-11-18
    • 2016-10-31
    • 2013-01-20
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2012-05-21
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多