【问题标题】:method annotations null when proxying via CGLIB通过 CGLIB 代理时方法注释为空
【发布时间】:2012-02-16 23:17:10
【问题描述】:

在通过反射查找属于通过 CGLIB 代理的类的方法上的注释时,我遇到了一种奇怪的行为。我们在 Spring 中使用 CGLIB,如果我仅使用注释对方法进行注释,则效果很好(我可以通过对应的 Method 对象上的 getAnnotations() 方法检索注释)。如果我用 2 个注释来注释方法(无论注释的顺序如何),getAnnotations() 只返回null。两个注释都有RetentionPolicy.RUNTIME

我读到 CGLIB 存在一些问题,但奇怪的是它只适用于一个注释,当我放置 2 个注释时它返回 null。

有什么建议吗?

(使用 Spring 3.0.5 和 CGLIB 2.2.2)

添加代码:

第一个注释是:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Produces {
    ResultType[] value();
}

第二个注释是

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JamonMonitored {
    String type() default "";
    String tag() default "";
}

代码块是用来检查注解的

Collection<Method> candidates = Collections2.filter(Arrays.asList(executorInstance.getClass().getMethods()), new Predicate<Method>() {
    @Override
    public boolean apply(Method input) {
        return input.getAnnotation(Produces.class) != null;
    }
});

if (candidates.isEmpty()) {
    // throws exception
}

如果我同时使用@Produces 和@JamonMonitored 注释一个方法,getAnnotation(Produces.class) 始终是null

【问题讨论】:

标签: java spring reflection annotations cglib


【解决方案1】:

另一个选项是在注解定义中指定@Inherited。这将使注释甚至出现在 cglib 生成的子类中。当然,在某些情况下,您不希望您的注释出现在“真正的”子类中,因此这可能不是每个场景的选项,而要走的路是使用 Spring 助手,如 skaffman 所示

【讨论】:

    【解决方案2】:

    CGLIB 通过生成目标对象类的子类来工作,并且该子类生成了委托给目标对象的方法。当您使用反射查询代理对象的注释时,您请求的是代理类的注释,而不是目标对象的类。

    Spring 必须自己进行大量注解处理,以便在代理、超类、接口等周围导航。这样做的逻辑被封装并暴露在org.springframework.core.annotation.AnnotationUtils 类中。就您而言,听起来您想要findAnnotation utility method,即

    @Override
    public boolean apply(Method input) {
        return AnnotationUtils.findAnnotation(input, Produces.class) != null;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多