spi 加載
這裏加上@LoadBalanced 註解的依賴注入,那麼就只有加了@LoadBalanced 的實例才能注入 進來,其實裏面有一個@Qualifier
只是這裏加上@LoadBalanced 註解才能依賴注入到源碼中的,如果不加這個註解則沒有 ribbon 功能,因爲源碼裏面獲取不到這個實例
把攔截器設置到 restTemplate 中
創建 Ribbon 客戶端對象
configurations 引用的實例化對象過程
restTemplate 的方法調用源碼
restTemplate 中設置的攔截器,攔截器先調用
核心源碼
獲取 ILoadBalancer 類型的實例
根據服務名稱創建一個容器,然後把容器根據服務名稱緩存,這裏在調用的時候獲取容器的 目的是爲了拿到最新的服務列表,所以 ribbon 在第一次服務名稱調用的時候是比較慢的, 涉及到創建容器過程,第二次就直接從緩存裏面拿容器對象了。
這裏創建容器對象,並且把兩個比較重要的類 register 進去了,register 其實就是把類變成 beanDefinition 對象,其實就是加載這兩個類到容器中,觸發這兩個類重新獲取服務列表
第一個註冊的類:
第二個註冊的類:
我們看看這兩個類: EurekaRibbonClientConfiguration 創建 serverList 對象
在 DiscoveryEnabledNIWSServerList 類中有一個特別重要的方法
這個方法裏面有一個方法是從本地從 eureka 服務端拉取到的服務列表的變量中獲取到服務 列表
另外一個類 RibbonClientConfiguration 這個類中有一個非常重要的方法,serverList 是從第一個註冊的類中實例化的,在這裏依賴 注入進來
返回的實例就是 ILoadBalanced 類型的,所以我們剛剛看到的
獲取到的實例就是 ZoneAwareLoadBalancer 實例。在該類實例化的構造函數中,最終會調到 其父類的構造函數,裏面有一個方法
這裏就掉到了這個核心方法,從本地服務列表中獲取到了服務列表信息
在看看獲取到這個實例化的接下來的操作
Server server = getServer(loadBalancer, hint);
這裏就是根據前面從本地服務列表中獲取到的列表信息,根據負載均衡算法從中獲取到一個
接下來就是具體 http 調用了,又會走回去,進到沒有攔截器的實例中