Spring隐藏的定制Java注释
在使用Spring和Jersey的REST服务上下文中,我创建了一个自定义注释,以便在运行时在方法级别上使用。然后我用它注释了一个方法,并通过反射,试图得到该方法的所有注释,但我总是得到零注释 自定义注释如下所示: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
@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$$D5843BAEClass
返回什么?您列出了getDeclaredMethods
返回的所有方法了吗?我想您说的是expert.getClass()
,它将返回一个@Component,该@Component预期从GenericeExpert抽象类继承。我还没有列出所有的方法,我只选择了我正在寻找的一种。是的。打印出该类的完全限定名。别猜了。这些都是您应该从开始的调试步骤。类名:com.rcs.template.experts.SampleExpert$$EnhancerBySpringCGLIB$$d5843baeYes,CGLIB是导致问题的原因。。。但我不知道如何将这些方法级注释继承到代理中,正如Sotirios所说,@Inherited仅用于类。是的,CGLIB是导致问题的原因。。。但我不知道如何将这些方法级注释继承到代理中,正如Sotirios所说,@Inherited只适用于类。