当通过CGLIB进行代理时,方法注释为null

man*_*nub 8 java reflection spring annotations cglib

当通过反射查看属于通过CGLIB代理的类的方法的注释时,我遇到了一种奇怪的行为.我们在Spring中使用CGLIB,如果我仅使用注释注释方法,则它可以正常工作(我可以通过getAnnotations()对应Method对象上的方法检索注释).如果我用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();
}
Run Code Online (Sandbox Code Playgroud)

第二个注释是

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

代码块用于检查注释

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
}
Run Code Online (Sandbox Code Playgroud)

如果我用@Produces和@JamonMonitored注释一个方法,getAnnotation(Produces.class)总是如此null.

ska*_*man 17

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

Spring必须自己进行大量的注释处理,以便在代理,超类,接口等方面进行导航.这样做的逻辑被封装并暴露在org.springframework.core.annotation.AnnotationUtils类中.在你的情况下,听起来你想要findAnnotation实用方法,即

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