javascript
@FeignClient中的@RequestMapping也被SpringMVC加载的问题解决
問題描述
在之前發布的《Spring Cloud實戰小貼士:Feign的繼承特性(偽RPC模式)》一文中,我們介紹了如果使用Feign的繼承特性來完成服務的提供以及服務的消費,實現了類似RPC的編程模式。但是,仔細一些的讀者可能已經發現一個問題:當我們將服務消費者運行起來的時候,定義在服務提供方的那些請求映射關系也被加載到了服務消費者中,這就會帶來兩個問題:
- 由于服務消費者并不提供這些接口,對于開發者來說容易造成誤解
- 由于加載了一些外部服務的接口定義,還存在與自身接口定義沖突的潛在風險
問題分析
那么這些外部請求接口定義是如何被加載到消費端的呢?我們先來看看Spring MVC處理請求映射的RequestMappingHandlerMapping實現片段:
protected boolean isHandler(Class<?> beanType) { return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class)); } |
我們可以發現如上的這段實現,該函數用來判斷是否要處理請求映射的判斷依據。從實現中我們看到,只要被掃描的類包含了@Controller注解或@RequestMapping注解,那么就會被加載進來。雖然@FeignClient定義修飾的服務消費端沒有聲明這些注解,但是當我們使用了繼承特性的時候,那么這些注解就也會被服務消費者解析和加載,所以出現了上面所描述的現象。
解決方法
既然已經找到了問題所在,那么我們可以針對性的擴展處理:擴展RequestMappingHandlerMapping的isHandler函數。
({Feign.class}) public class FeignConfiguration { public WebMvcRegistrations feignWebRegistrations() { return new WebMvcRegistrationsAdapter() { public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new FeignRequestMappingHandlerMapping(); } }; } private static class FeignRequestMappingHandlerMapping extends RequestMappingHandlerMapping { protected boolean isHandler(Class<?> beanType) { return super.isHandler(beanType) && !AnnotatedElementUtils.hasAnnotation(beanType, FeignClient.class); } } } |
如上實現的isHandler函數繼承了原來的實現,同時增加了一個條件:不能被@FeignClient注解修飾的類才會進行解析加載。
相關閱讀
- Spring Cloud實戰小貼士:Feign的繼承特性(偽RPC模式)
- Spring Cloud構建微服務架構:服務消費者(Feign)【Dalston版】
- Spring Cloud構建微服務架構:服務消費者(Ribbon、Feign)
- 探討通過Feign配合Hystrix進行調用時異常的處理
總結
以上是生活随笔為你收集整理的@FeignClient中的@RequestMapping也被SpringMVC加载的问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis系列教程(七):Redis并发
- 下一篇: 基于 KIF 的 iOS UI 自动化测