【问题标题】:Retain annotations on CGLIB proxies?保留 CGLIB 代理上的注释?
【发布时间】:2010-12-14 23:20:38
【问题描述】:

我正在尝试使用 AOP 框架创建对象,该框架使用 CGLIB 创建代理对象。 奇怪的是,“增强的”代理对象没有前一个类的任何注释!

谁能告诉我如何让 CGLIB 保留它创建的代理上的注释?

干杯! 尼拉夫

【问题讨论】:

  • @Inherited 注解是否解决了问题?如果是这样,您可以考虑批准答案。谢谢。
  • @Inherited 没有解决问题(我自己试过了)。我个人使用的是 Spring 项目并通过使用 AnnotationUtils 实用程序类来解决,因此您可以看到 here 它是如何工作的。

标签: java annotations cglib


【解决方案1】:

CGLIB 创建给定类的子类以生成代理。除非在注释定义中明确指定,否则注释不会保留在子类中。 @Inherited 注解用于此目的。

您可以在定义的注解中使用该注解,并使其在子类中可访问,如下所示:

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}

【讨论】:

  • 我遇到了这个问题,而且您的修复似乎不起作用。
  • @Inherited 仅在注解的目标是一个类时有效 - 您的子类代理的方法仍然没有注解。
  • 我不知道是否适用于注解类,但方法仍然没有注解。
【解决方案2】:

这不是“保留”注释的问题。 CGLIB 代理实际上是生成的目标对象类的子类。这些子类可能没有注释,但它们的超类(即您自己的类)仍然有它们。您使用的任何注解反射代码都需要能够回溯类层次结构以查找注解。

【讨论】:

    【解决方案3】:

    Cglib 不能在不更改其内部实现的情况下保留注释。然而,这很复杂,相信我我试过了。然而,我最终想出的修改后的版本非常复杂,因此我决定实现 Byte Buddy,这是另一个能够实现此类功能的代码生成库。

    这是一个如何创建子类的示例

    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation { }
    
    @MyAnnotation
    class MyClass { }
    
    assertThat(new ByteBuddy()
      .subclass(Object.class)
      .attribute(TypeAttributeAppender.ForSuperType.INSTANCE)
      .make()
      .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
      .getLoaded()
      .isAnnotationPresent(MyAnnotation.class), is(true));
    

    Byte Buddy 附带一个广泛的全文文档和 javadoc,它具有相当的可扩展性。希望你好好利用这个库。

    【讨论】:

      【解决方案4】:

      这是一个有效的问题(我现在自己也遇到了),因为 a) 并非所有框架都足够聪明,可以检查父类 b) 即使它们足够聪明,他们也可能选择不这样做。后者似乎是 Guice 的情况。 FWIW,https://issues.apache.org/jira/browse/WICKET-1130 是我发现这个问题时正在解决的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-16
        • 1970-01-01
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 2015-07-27
        相关资源
        最近更新 更多