程序員不可不學(xué)的REST服務(wù)集成,F(xiàn)eign實(shí)現(xiàn)REST調(diào)用?
Feign實(shí)現(xiàn)REST調(diào)用
Feign 是 一 個(gè) 聲 明 式 的 Web Service 客 戶 端 , 它 使 得 編 寫 WebService客戶端更為容易。Feign受到Retrofit、JAXRS2.0、WebSocket的影響,采用聲明式的API調(diào)用模式。

Feign的特征
● Feign基于聲明式的REST調(diào)用方式,相比Rest-Template、HTTPClient等命令性HTTP客戶端,F(xiàn)eign通過代理模式屏蔽了調(diào)用方與底層HTTPClient技術(shù)耦合的調(diào)用細(xì)節(jié)。Feign的調(diào)用就像使用本地方法調(diào)用完成服務(wù)的請(qǐng)求。
● Feign簡化了請(qǐng)求的編寫,可以動(dòng)態(tài)地選擇使用HTTP客戶端實(shí)現(xiàn),可以結(jié)合Eureka、Ribbon、Hystrix等組件實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)、負(fù)載均衡、熔斷等。
● Spring Cloud對(duì)Feign進(jìn)行了封裝,它支持可插拔的注解,所以支持Spring MVC標(biāo)準(zhǔn)注解和使用HttpMessageConverters模塊做消息轉(zhuǎn)換。
● Feign可以對(duì)請(qǐng)求進(jìn)行攔截,提供HTTP模板,使用簡單的注解和配置實(shí)現(xiàn)定義HTTP請(qǐng)求的參數(shù)、格式、地址等信息。它支持可插拔的HTTP編碼器和解碼器等。
Feign的使用方法
首先,需要在pom.xml文件中引入對(duì)Feign的依賴:

其次,創(chuàng)建應(yīng)用主類Application,并通過@EnableFeignClients注解開啟Spring Cloud Feign的支持功能:

然后,定義DemoServiceFeign接口,接口中使用@FeignClient注解指定服務(wù)名來綁定服務(wù),之后使用Spring MVC的注解來綁定具體該服務(wù)提供的REST接口功能:

最后,創(chuàng)建一個(gè)RestClientServcie服務(wù)來實(shí)現(xiàn)對(duì)Feign客戶端的調(diào)用,使用@Autowired直接注入上面定義的HelloServiceFeign實(shí)例:


Feign的源碼解析
Feign是一個(gè)偽Java HTTP客戶端,F(xiàn)eign本身不做任何請(qǐng)求處理。
Feign借鑒AOP設(shè)計(jì)思想,通過注解生成HTTP Request模板,從而簡化HTTP API的開發(fā)。我們可以使用注解的方式定制Request API模板,分離HTTP請(qǐng)求使用者與具體實(shí)現(xiàn)。下面從注解@EnableFeignClients開始講解,深入理解Feign聲明式的HTTP客戶端的調(diào)用過程。
@EnableFeignClients的主要注解聲明如下:

注解@EnableFeignClients告訴Spring Boot容器掃描所有使用注解 @FeignClient 定 義 的 Feign 客 戶 端 。通 過 注 解 @Import 導(dǎo) 入FeignClientsRegistrar類。
FeignClientsRegistrar類實(shí)現(xiàn)了接口
ImportBeanDefinitionRegistrar,這個(gè)接口的設(shè)計(jì)目的就是被某個(gè)實(shí)現(xiàn)類實(shí)現(xiàn),配合@Configuration注解的使用者配置類使用,在配置類被處理時(shí),用于額外注冊(cè)一部分Bean定義,代碼如下:

@EnableFeignClients注解被處理時(shí)的調(diào)用棧如下:


在程序啟動(dòng)后,程序會(huì)通過包掃描將由@FeignClient注解修飾的接 口 連 同 接 口 名 和 注 解 信 息 一 起 取 出 , 賦 值 給BeanDefinitionBuilder , 再 根 據(jù) BeanDefinitionBuilder 得 到BeanDefinition,最后將BeanDefinition注入Spring IoC容器中,源碼如下:

在 注 入 BeanDefinition 之 后 , 通 過 JDK 動(dòng) 態(tài) 代 理 機(jī) 制 生 成FeignClient代理對(duì)象,使用FeignClient接口里面的方法時(shí),方法會(huì)被攔截,源碼在ReflectiveFeign類中,如下所示:


從 factory.create ( target , methodToHandler ) 可 以 看 出 ,InvocationHandler 實(shí) 際 委 托 給 了 methodToHandler , 而methodToHandler默認(rèn)是
SynchronousMethodHandler.Factory工廠類創(chuàng)建的,newInstance方法最終生成Feign的動(dòng)態(tài)代理。
在 調(diào) 用 過 程 中 , Feign 首 先 會(huì) 通 過 代 理 對(duì) 象 調(diào) 用FeignInvocationHandler的invoke方法,代碼如下:

最 終 , 在 methodToHandler 匹 配 成 功 后 , 調(diào) 用SynchronousMethodHandler類的invoke方法進(jìn)行HTTP攔截。它會(huì)根據(jù)參數(shù)生成RequestTemplate對(duì)象,該對(duì)象是HTTP請(qǐng)求模板,其中的executeAndDecode方法會(huì)執(zhí)行HTTP請(qǐng)求,并獲取Response響應(yīng),代碼如下:

本文給大家講解的內(nèi)容是REST服務(wù)集成,F(xiàn)eign實(shí)現(xiàn)REST調(diào)用
下篇文章給大家講解的內(nèi)容是RPC遠(yuǎn)程過程調(diào)用,RPC框架概述
覺得文章不錯(cuò)的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
感謝大家的支持!
本文就是愿天堂沒有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學(xué)習(xí)更多的話可以到微信公眾號(hào)里找我,我等你哦。
