Feign源碼解析(一)

引言

??工作日常使用到了feign,幾年前曾看過(guò)源碼,由于當(dāng)時(shí)沒(méi)有閱讀過(guò)spring ioc等部分的源碼,對(duì)于feign這部分理解很多地方都不太清楚。在此五一期間,再閱讀一遍,此系列為記錄閱讀過(guò)程,僅僅提供閱讀思路,如果錯(cuò)誤理解,請(qǐng)及時(shí)指出。

目標(biāo)

  • 搞明白Feign實(shí)現(xiàn)原理
  • 找到其設(shè)置的擴(kuò)展點(diǎn),用于將來(lái)進(jìn)行擴(kuò)展

RPC (Remote Procedure Call )

??RPC 全稱(chēng)是 Remote Procedure Call ,即遠(yuǎn)程過(guò)程調(diào)用,其對(duì)應(yīng)的是我們的本地調(diào)用。RPC 的目的是:讓我們調(diào)用遠(yuǎn)程方法像調(diào)用本地方法一樣。依稀記得很多年前還學(xué)習(xí)過(guò) Java RMI(Java Remote Method Invocation), 隨著Java Web以及微服務(wù)的興起,已經(jīng)銷(xiāo)聲匿跡,作為遠(yuǎn)程調(diào)用寵兒。Dubbo與Feign是比較常見(jiàn)的RPC技術(shù),話不多說(shuō),今天先簡(jiǎn)單介紹Feign的基本知識(shí),開(kāi)始Feign源碼的閱讀之旅。


RPC框架設(shè)計(jì).png

什么是Feign

??Feign是Netflix開(kāi)發(fā)的聲明式、模板化的HTTP客戶端,F(xiàn)eign可幫助我們更加便捷、優(yōu)雅地調(diào)用HTTP API。
??Feign可以做到使用 HTTP 請(qǐng)求遠(yuǎn)程服務(wù)時(shí)就像調(diào)用本地方法一樣的體驗(yàn),開(kāi)發(fā)者完全感知不到這是遠(yuǎn)程方法,更感知不到這是個(gè) HTTP 請(qǐng)求。它像 Dubbo 一樣,consumer 直接調(diào)用接口方法調(diào)用 provider,而不需要通過(guò)常規(guī)的 Http Client 構(gòu)造請(qǐng)求再解析返回?cái)?shù)據(jù)。它解決了讓開(kāi)發(fā)者調(diào)用遠(yuǎn)程接口就跟調(diào)用本地方法一樣,無(wú)需關(guān)注與遠(yuǎn)程的交互細(xì)節(jié),更無(wú)需關(guān)注分布式環(huán)境開(kāi)發(fā)。
??Spring Cloud openfeign對(duì)Feign進(jìn)行了增強(qiáng),使其支持Spring MVC注解,另外還整合了Ribbon和Eureka,從而使得Feign的使用更加方便。

SpringCloud中如何使用Feign

??通過(guò)以下4步就可以實(shí)現(xiàn)Feign的調(diào)用實(shí)現(xiàn),實(shí)際在使用過(guò)程中可能會(huì)遇到各種其他的情況,大部分開(kāi)發(fā)人員對(duì)Feign的認(rèn)識(shí)也止步于此,還有一部分開(kāi)發(fā)人員憑借經(jīng)驗(yàn)來(lái)解決問(wèn)題(曾經(jīng)的自己)。

  1. 引入依賴
 <!-- openfeign 遠(yuǎn)程調(diào)用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
  1. 啟動(dòng)類(lèi)啟用Feign
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class AuthApplication {

    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class, args);
    }
}
  1. 書(shū)寫(xiě)FeignClient接口
@FeignClient(value = "test-center", fallback = SecurityFeignFallback.class)
public interface TestFeign {

    @RequestMapping(value = "/jwt/test", method = RequestMethod.POST)
    ResponseResult<String> test(@RequestBody SystemInfo systemInfo);
}
  1. 注入調(diào)用
@Autowired
private TestFeign  testFeign;

public String test() {
   SystemInfo systemInfo = new SystemInfo();
   testFeign.test(systemInfo);
   return "ok";
}

Feign設(shè)計(jì)架構(gòu)

??以下是Feign整體的設(shè)計(jì)架構(gòu),可以看出主要采用的有動(dòng)態(tài)代理技術(shù)以及加解碼


Feign設(shè)計(jì)架構(gòu).png

為什么要閱讀源碼

  1. 求知欲,開(kāi)發(fā)人員基本素養(yǎng)。
  2. 熟悉非直接研發(fā)代碼,了解整個(gè)調(diào)用鏈路,方便問(wèn)題的排查與開(kāi)發(fā)的擴(kuò)展,豐富解決方案,拓展思路。
  3. 向開(kāi)源代碼學(xué)習(xí),在日常研發(fā)時(shí),規(guī)范或者優(yōu)雅的進(jìn)行研發(fā),這里并非只有代碼,注釋等同樣值得學(xué)習(xí)。

問(wèn)題

在閱讀源碼之前先提出幾個(gè)很容易遇到的問(wèn)題,可以想一下答案:

  1. FeignClient已經(jīng)聲明,引入時(shí)為何報(bào)錯(cuò),無(wú)法注入
  2. 如何加入Request Header
  3. 如何實(shí)現(xiàn)上傳文件(單個(gè)或者多個(gè)文件)
  4. 如何將默認(rèn)的Jackson替換為Fastjson
    簡(jiǎn)單提出以上4個(gè)問(wèn)題,如果有可以補(bǔ)充的留言區(qū)哦。以上是源碼解析第一章,接下來(lái)將進(jìn)入正題環(huán)節(jié)。

展望

  • Feign代碼入口尋找(Feign源碼解析(一))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容