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