springcloud微服務架構之feign組件的源碼分析

1. feign概述

Feign是接口調用的,但是衆所周知接口是不能創建對象的,必須有實現類。而Feign的做法類似於Mybatis中mapper接口的實現,都是利用了動態代理來給接口創建一個代理對象,創建好的代理對象完成真正的調用過程。

2. 案例入門

在這裏插入圖片描述

  • Eureka Server:
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 服務提供者:
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 服務調用者feign
    在這裏插入圖片描述
    複製對應的方法簽名到接口中,並標識對應的註解,以便Spring框架對其進行動態代理創建代理對象:
    在這裏插入圖片描述
    依次啓動:
    在這裏插入圖片描述
3. feign具體步驟

① 先給接口創建對象;
② 代理對象執行進入invoke方法;
③在invoke方法中執行遠程調用;
    a. 讀取註解得到要調用的遠程接口,provider/info;
    b. 通過ribbon+restTemplate的負載得到一個要調用的真實服務提供者;
    c. 發起請求得到響應;

4 . Feign的內部怎麼實現的
  • @EnableFeignClients註解中引入了FeignClientsRegistrar類:
    在這裏插入圖片描述
  • 該類中實現了ImportBeanDefinitionRegistrar,可以將需要創建的對象放在註冊器裏面,以便spring動態代理幫我們創建代理對象:
    在這裏插入圖片描述
  • 在feign中我們可以將那些接口傳入FeignClientsRegistrar類的以下方法中,將@FeignClient標記的接口放在registry註冊器中,spring之後幫我們創建對象:
    在這裏插入圖片描述
  • 上面的registerFeignClients()方法會做包掃描,得到所有@FeignClient標記的接口:
    在這裏插入圖片描述
  • 上面最後一行代碼registerFeignClient(registry, annotationMetadata, attributes);將要創建接口的代理對象的信息放在registry裏面。
  • 接下來,在ReflectiveFeign的newInstance()方法中創建對應的代理對象,可以從中看到我們熟悉的代碼:
    在這裏插入圖片描述
  • 但是這次的InvocationHandler是已經被提前實現的靜態內部類:
    在這裏插入圖片描述
  • InvocationHandler類中的invoke()方法是代理的關鍵,此處相當於我們之前動態代理中自己實現的InvocationHandler匿名類:
    在這裏插入圖片描述
  • return dispatch.get(method).invoke(args);是真正的執行。創建一個RequestTemplate 對象
    在這裏插入圖片描述
  • executeAndDecode(template);繼續調用:
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
5. feign源碼總結
  • feign通過ReflectiveFeign的newInstance()方法中的InvocationHandler handler = factory.create(target, methodToHandler)完成代理對象的創建,可以看出feign的本質就是代理對象的調用。
  • 在ReflectiveFeign.FeignInvocationHandler是實現了JDK 的InvocationHandler
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章