feign 面試


 

https://blog.csdn.net/nihui123/article/details/107018787

整體的遠程調用執行流程,大致分為4步,具體如下:

第1步:通過Spring IOC 容器實例,裝配代理實例,然后進行遠程調用。

  上面說到,Feign在啟動時,會為加上了@FeignClient注解的所有遠程接口創建一個本地JDK Proxy代理實例,並注冊到Spring IOC容器。在這里,暫且將這個Proxy代理實例,叫做 DemoClientProxy,稍后,會詳細介紹這個Proxy代理實例的具體創建過程。
  然后,在UserController 調用代碼中,通過@Resource注解,按照類型或者名稱進行匹配,當然也可以使用其他方式。由於使用的SpringIOC所以還可以使用@Autowire 。從Spring IOC容器找到這個代理實例,並且裝配給@Resource注解所在的成員變量。也就是之前提到的被使用的FeginDemo
  例如,在需要代理進行hello()遠程調用時,直接通過 feginDemo 成員變量,調用JDK Proxy動態代理實例的hello()方法。
第2步:執行 InvokeHandler 調用處理器的invoke(…)方法
  前面講到,JDK Proxy動態代理實例的真正的方法調用過程,具體是通過 InvokeHandler 調用處理器完成的。故,這里的DemoClientProxy代理實例,會調用到默認的FeignInvocationHandler 調用處理器實例的invoke(…)方法。
  通過前面 FeignInvocationHandler 調用處理器的詳細介紹,已經知道,默認的調用處理器 FeignInvocationHandle,內部保持了一個遠程調用方法實例和方法處理器的一個Key-Value鍵值對Map映射。FeignInvocationHandle 在其invoke(…)方法中,會根據Java反射的方法實例,在dispatch 映射對象中,找到對應的 MethodHandler 方法處理器,然后由后者完成實際的HTTP請求和結果的處理。
  所以在第2步中,FeignInvocationHandle 會從自己的 dispatch映射中,找到hello()方法所對應的MethodHandler 方法處理器,然后調用其 invoke(…)方法。

第3步:執行 MethodHandler 方法處理器的invoke(…)方法

  通過前面關於 MethodHandler 方法處理器的非常詳細的組件介紹,大家都知道,feign默認的方法處理器為 SynchronousMethodHandler,其invoke(…)方法主要是通過內部成員feign客戶端成員 client,完成遠程 URL 請求執行和獲取遠程結果。
feign.Client 客戶端有多種類型,不同的類型,完成URL請求處理的具體方式不同。

第4步:通過 feign.Client 客戶端成員,完成遠程 URL 請求執行和獲取遠程結果

  如果MethodHandler方法處理器實例中的client客戶端,是默認的 feign.Client.Default 實現類性,則使用JDK自帶的HttpURLConnnection類,完成遠程 URL 請求執行和獲取遠程結果。

  如果MethodHandler方法處理器實例中的client客戶端,是 ApacheHttpClient 客戶端實現類性,則使用 Apache httpclient 開源組件,完成遠程 URL 請求執行和獲取遠程結果。

通過以上四步,應該可以清晰的了解到了 SpringCloud中的 feign 遠程調用執行流程和運行機制。

補充
  實際上,為了簡明扼要的介紹清楚默認的調用流程,上面的流程,實際上省略了一個步驟:第3步,實際可以分為兩小步。為啥呢?
  SynchronousMethodHandler 並不是直接完成遠程URL的請求,而是通過負載均衡機制,定位到合適的遠程server 服務器,然后再完成真正的遠程URL請求。
  換句話說,SynchronousMethodHandler實例的client成員,其實際不是feign.Client.Default類型,而是 LoadBalancerFeignClient 客戶端負載均衡類型。
   因此,上面的第3步,如果進一步細分話,大致如下:

    • (1)首先通過 SynchronousMethodHandler 內部的client實例,實質為負責客戶端負載均衡LoadBalancerFeignClient 實例,首先查找到遠程的 server 服務端;
    • (2) 然后再由LoadBalancerFeignClient 實例內部包裝的feign.Client.Default 內部類實例,去請求server端服務器,完成URL請求處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM