Feign源碼分析


git地址
https://github.com/a18792721831/studySpringCloud.git

1. Feign工作原理

項目需要集成Feign,那麼就需要在main方法對應的類上加上Feign開啓的註解@EnableFeignClients
進入@EnableFeignClients註解
在這裏插入圖片描述
FeignClientsRegistrar
在這裏插入圖片描述
會進行一些處理
在這裏插入圖片描述
Feign 通過包掃描注入 FeignClient 的 Bean,該源碼在FeignClientsRegistrar類中。首先在程序啓動時,會檢查是否有@EnableFeignClients註解,如果有該註解,則開啓包掃描,掃描被@FeignClient 註解的接口。
在這裏插入圖片描述
通過斷點調試,當程序的啓動類上有@EnablefeignClients 註解。在程序啓動後,程序會通過包掃描將有
@FegaClient註解修飾的接口連同接口名和註解的信息一起取出,賦給 BeanDefinitionBuilde然後根據BeanDefnitionBuilder 得到BeanDefinition,最後將 BeanDefinition 注入IoC 容器中。
在這裏插入圖片描述
在這裏插入圖片描述
注入BeanDefinition之後,通過JDK的代理,當調用Feign Cleint接口裏面的方法時,該方法會被攔截。
在這裏插入圖片描述
在這裏插入圖片描述
在SynchronousMethodHandler類進行攔截處理,會根據參數生成RequestTemplate對象,該對象是Http請求的模板。
在這裏插入圖片描述
executeAndDecode方法通過RequestTemplate生成Reques請求對象,然後用Http Client獲取Rqsponse,即通過Http Client進行Http請求獲取響應。
在這裏插入圖片描述

2. Feign使用HttpClient和OkHttp

首先查看FeignRibbonClient的自動配置類,該類在工程啓動時注入一些Bean,其中注入了一個BeanName爲FeignClient的Bean
在這裏插入圖片描述在這裏插入圖片描述
在缺省配置BeanName爲FeignClient的Bean的情況下,會自動注入Client.Default這個對象。
在這裏插入圖片描述
我們剛纔看了默認的配置,上面之前Import還有其他兩個類
在這裏插入圖片描述
這是HttpClient
在這裏插入圖片描述
發現代碼提示異常,是ApacheHttpClient的依賴未找到。
所以,只需要我們加入這個依賴就能使用HttpClient作爲Feign的請求。
在這裏插入圖片描述
從@ConditionalOnProperty中看出,需要在配置文件將feign.httpclient.enabled設置爲true.當然,也可以不寫,默認爲true
接下來看OkHttp
在這裏插入圖片描述
OkHttp上面的註解就沒有默認值了,所以OkHttp就需要配置了,
在這裏插入圖片描述
因爲默認是false.
在這裏插入圖片描述

3. Feign是如何實現負載均衡

當程序的啓動類上有@EnablefeignClients 註解。在程序啓動後,程序會通過包掃描將有@FegaClient註解修飾的接口連同接口名和註解的信息一起取出,賦給 BeanDefinitionBuilde然後根據BeanDefnitionBuilder 得到BeanDefinition,最後將 BeanDefinition 注入IoC 容器中。
在這裏插入圖片描述
其中有一個executeWithLoadBalancer方法,通過負載均衡的方式執行網絡請求。
在這裏插入圖片描述
進入commit方法,,內部是LoadBalancerCommand的方法
在這裏插入圖片描述
selectServer方法就是選擇服務進行負載均衡
在這裏插入圖片描述
到了這裏,又到了RibbonLoadBalancer的loadBalancerContext進行處理,即交由Ribbon進行處理了。

總的來說,Feign的源碼實現過程如下。

  • (1)首先通過@EnableFeignClients 註解開啓 FeignClient的功能。只有這個註解存在,纔會在程序啓動時開啓對@FeignClient註解的包掃描。
  • (2)根據Feign的規則實現接口,並在接口上面加上@FcignClient註解。
  • (3)程序啓動後,會進行包掃描,掃描所有的@ FeignClient 的註解的類,並將這些信息注入IoC 容器中。
  • (4)當接口的方法被調用時,通過JDK 的代理來生成具體的 RequestTemplate 模板對象。
  • (5)根據 RequestTemplate 再生成 Http 請求的 Request對象。
  • (6)Request 對象交給 Client 去處理,其中 Client 的網絡請求框架可以是 HttpURLConnection、HttpClient 和 OkHttp。
  • (7)最後Client被封裝到LoadBalanceClient類,這個類結合類Ribbon做到了負載均衡。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章