Spring隐藏的定制Java注释

Spring隐藏的定制Java注释,java,spring,reflection,annotations,Java,Spring,Reflection,Annotations,在使用Spring和Jersey的REST服务上下文中,我创建了一个自定义注释,以便在运行时在方法级别上使用。然后我用它注释了一个方法,并通过反射,试图得到该方法的所有注释,但我总是得到零注释 自定义注释如下所示: @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RestMethod { } 然后,方法注释为: @Service public clas

在使用Spring和Jersey的REST服务上下文中,我创建了一个自定义注释,以便在运行时在方法级别上使用。然后我用它注释了一个方法,并通过反射,试图得到该方法的所有注释,但我总是得到零注释

自定义注释如下所示:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RestMethod {
}
然后,方法注释为:

@Service
public class SampleExpert extends GenericExpert {
...

    @RestMethod
    public PaginationDTO<SampleDTO> list(SamplePaginationFiltersDTO filters) {
    ...
    }
}
在这里,logger.info(“注释数:”+…)始终打印:

18:31:31,837 INFO  [http-apr-8080-exec-7][RestResponder:60] Number of annotations: 0
但是,如果我执行以下操作:

Method m = SampleExpert.class.getMethod("list", SamplePaginationFiltersDTO.class);
logger.info("Number of annotations: " + m.getAnnotations().length);
我得到了适当数量的注释(本例中为1)


我猜Spring正在用一个代理来包装这个方法,这就是为什么我没有得到这个方法的注释,而是得到了代理中的注释。我还没有找到任何解决这种情况的方法。

问题是Spring为您的对象创建代理,所以当您创建代理时

(GenericExpert) ctx.getBean(expertName + "Expert");
实际上,您得到的是代理对象,而不是预期的
SampleExpert

@Inherited
注释添加到您的
RestMethod
注释中。默认情况下,即使是常规子类也不会继承注释,更不用说代理了

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RestMethod {
}

如果这不起作用,请确保使用了
CGLIB
代理(可能是因为您将其用于非接口类)。

问题在于Spring为您的对象创建代理,所以当您这样做时

(GenericExpert) ctx.getBean(expertName + "Expert");
实际上,您得到的是代理对象,而不是预期的
SampleExpert

@Inherited
注释添加到您的
RestMethod
注释中。默认情况下,即使是常规子类也不会继承注释,更不用说代理了

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RestMethod {
}

如果这不起作用,请确保使用了
CGLIB
代理(可能是因为您将其用于非接口类)。

我终于找到了问题的答案。我需要使用
org.springframework.core.annotation.AnnotationUtils
实用程序类来检查注释是否存在,如下所示:

AnnotationUtils.findAnnotation(m, RestMethod.class) != null

Spring的
AnnotationUtils.findAnnotation()
方法正确地克服了CGLIB引入的问题。

我终于找到了问题的答案。我需要使用
org.springframework.core.annotation.AnnotationUtils
实用程序类来检查注释是否存在,如下所示:

AnnotationUtils.findAnnotation(m, RestMethod.class) != null

Spring的
AnnotationUtils.findAnnotation()
方法正确地克服了CGLIB引入的问题。

getClass
返回了什么?您列出了
getDeclaredMethods
返回的所有方法了吗?我想您说的是
expert.getClass()
,它将返回一个@Component,该@Component预期从GenericeExpert抽象类继承。我还没有列出所有的方法,我只选择了我正在寻找的一种。是的。打印出该类的完全限定名。别猜了。这些都是您应该从开始的调试步骤。类名:com.rcs.template.experts.SampleExpert$$EnhancerBySpringCGLIB$$D5843BAE
Class
返回什么?您列出了
getDeclaredMethods
返回的所有方法了吗?我想您说的是
expert.getClass()
,它将返回一个@Component,该@Component预期从GenericeExpert抽象类继承。我还没有列出所有的方法,我只选择了我正在寻找的一种。是的。打印出该类的完全限定名。别猜了。这些都是您应该从开始的调试步骤。类名:com.rcs.template.experts.SampleExpert$$EnhancerBySpringCGLIB$$d5843baeYes,CGLIB是导致问题的原因。。。但我不知道如何将这些方法级注释继承到代理中,正如Sotirios所说,@Inherited仅用于类。是的,CGLIB是导致问题的原因。。。但我不知道如何将这些方法级注释继承到代理中,正如Sotirios所说,@Inherited只适用于类。