2015-12-02 64 views
0

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

自定义注释是这样的:

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

然后,方法注释:

@Service 
public class SampleExpert extends GenericExpert { 
... 

    @RestMethod 
    public PaginationDTO<SampleDTO> list(SamplePaginationFiltersDTO filters) { 
    ... 
    } 
} 

而且最重要的部分,代码试图获取方法列表的所有注释的部分()得到一个零元素数组:

@POST 
@Path("/{expert}/{method}") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public Response post(@PathParam("expert") String expertName, @PathParam("method") String methodName, @Context HttpServletRequest request, String data) { 
    try { 
     logger.debug("Invoking {}.{}()", WordUtils.capitalize(expertName) + "Expert", methodName); 

     // Get Bean and Method. 
     WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext()); 
     GenericExpert expert = (GenericExpert) ctx.getBean(expertName + "Expert"); 
     Method method = null; 
     for (Method m : expert.getClass().getDeclaredMethods()) { 
      if (m.getName().equals(methodName)) { 
       logger.info("Number of annotations: " + m.getAnnotations().length); 
       method = m; 
       break; 
      } 
     } 
    ... 
} 

这里,logger.info(“Number of ann otations:“+ ...)始终打印:

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适当数量的,在这种情况下)。

我想春天是用代理包装方法,这就是为什么我没有得到方法的注释,但代理中的注释。我一直无法找到解决这种情况的办法。

+0

什么'类''getClass'返回?你列出了所有'getDeclaredMethods'返回的方法吗? –

+0

我想你正在讨论'expert.getClass()',它将返回一个@Component,它将从GenericExpert抽象类继承。 我还没有列出所有的方法,我只选了一个我正在寻找的方法。 –

+0

是的。打印出该类的完全限定名称。不要猜测。这些都是您应该从头开始的所有调试步骤。 –

回答

1

我终于得到了我的问题的答案。我需要使用org.springframework.core.annotation.AnnotationUtils实用工具类,以检查是否注释存在,这样的:

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

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

+0

感谢您节省我的时间。 – Junjie

-1

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

(GenericExpert) ctx.getBean(expertName + "Expert"); 

你实际得到的,而不是SampleExpert那你希望代理对象。

@Inherited注释添加到您的RestMethod注释中。即使通过常规子类,注释也不会被默认继承,更不用说代理。

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

如果不工作,确保CGLIB代理使用(他们很可能是因为你是与非接口类使用它)。

+1

'@ Inherited'仅适用于类注解。 –

+0

是的,CGLIB是什么导致问题...但我不知道如何将这些方法级别的注释继承到代理,并且Sotirios说,@Inherited仅适用于类。 –