2015-12-02 67 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僅適用於類。 –