上一篇我們講到了由攔截器攔截下來請求後,真正的處理其實是在LoadBalancerClient的execute方法中的,LoadBalancerClient是在構造LoadBalancerInterceptor的時候直接傳進來的,但是這個LoadBalancerClient,是如何完成實例化的?
實際上攔截器就是很薄很薄的一層,他是把請求交給LoadBalancerClient,這纔是真正的重頭戲。
尋找LoadBalancerClient實例化的艱難過程:
1、LoadBalancerAutoConfiguration中沒找到構造LoadBalancerClient的相關代碼
2、分析+推測:LoadBalancerClient是一個接口,既然是@Bean方法裏傳進來了一個LoadBalancerClient,肯定是LoadBalancerClient有個實現類,在別的地方,對這個實現類構造了一個實例,然後打成了一個@Bean,作爲spring容器裏可以管理的一個bean
只有這種可能,纔可以在這裏講LoadBalancerClient傳進來
3、org.springframework.cloud.client.loadbalancer這個包裏也沒找到
4、spring-cloud-commons工程也是沒有的。
5、找一下netflix ribbon原生的jar包裏有沒有線索,最終結果也都是沒找到!!!
(1)ribbon-2.2.5.jar:理解爲ribbon的內核級別的比較核心的一些組件
(2)ribbon-transport-2.2.5.jar:基於netty封裝的特別底層的進行http、tcp、udp各種協議的網絡通信的組件
(3)ribbon-core-2.2.5.jar:推測這是ribbon比較基礎性的一些通用的代碼組件
(4)ribbon-httpclient-2.2.5.jar:是ribbon底層的http網絡通信的一些組件
(5)ribbon-loadbalancer-2.2.5.jar:都是ribbon最最核心的原生的API
6、分析+推測:肯定是交給ribbon的相關的類去處理的,而且在這裏肯定找到的不是ribbon原生的api,肯定找的是spring cloud ribbon項目裏面的類。發現spring-cloud-starter-ribbon和spring-cloud-starter-netflix-ribbon中依賴了大量的netflix ribbon原生的jar包
spring-cloud-starter-netflix-ribbon,沒一行代碼,分析一下pom.xml,唯一找到的一個希望是這個項目:spring-cloud-netflix-core,只有他了,纔有這個希望,可以找到所謂的ribbon的LoadBalancerClient
結果發現柳暗花明又一村,發現點開這個工程,一大堆代碼,hystrix、zuul、feign、ribbon,這個裏面很明顯就是放了什麼呢?放了spring cloud跟netflix相關的技術進行整合的膠水代碼
我們到ribbon相關的包下面去找找,有沒有對應的LoadBalancerClient。。。
找到了什麼呢?RibbonLoadBalancerClient,這個東東就是實際的請求執行的入口。
7、已經知道了用的是哪個LoadBalancerClent,但是現在另外一個問題來了?如何將這個RibbonLoadBalancerClient創建爲一個Bean的呢?
推測:是不是什麼AutoConfiguration相關的類,或者是Configuration相關的類,或者是Config相關的類,初始化了一個RibbonLoadBalancerClient的Bean呢?
8、找到RibbonAutoConfiguration這個配置類。
這個RibbonAutoConfiguration,必須在之前看的那個LoadBalancerAutoConfiguration之前來執行,LoadBalancerAutoConfiguration觸發的一些列的代碼,是依賴於LoadBalancerClient的,但是LoadBalancerClient的初始化是在RibbonAutoConfiguration裏執行的,所以必須是RibbonAutoConfiguraiton先執行,先初始化一個RibbonLoadBalancerClient纔可以。
//RibbonAutoConfiguration必須在EurekaClientAutoConfiguration之後來執行的,也就是說eureka必須先初始化完,纔會輪到ribbon來初始化
@AutoConfigureAfter(name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration")
//RibbonAutoConfiguration必須在之前看的那個LoadBalancerAutoConfiguration之前來執行
@AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class})
public class RibbonAutoConfiguration {
//代碼細節省略。。。
}
9、終於找到LoadBalancerClient實例化的方法
完美定位,找到了,LoadBalancerClient是哪兒來的?其實是這兒來的,這兒直接是創建了一個對應的LoadBalancerClient:RibbonLoadBalancerClient實例。
//RibbonAutoConfiguration必須在EurekaClientAutoConfiguration之後來執行的,也就是說eureka必須先初始化完,纔會輪到ribbon來初始化
@AutoConfigureAfter(name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration")
//RibbonAutoConfiguration必須在之前看的那個LoadBalancerAutoConfiguration之前來執行
@AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class})
public class RibbonAutoConfiguration {
//代碼細節省略。。。
@Bean
@ConditionalOnMissingBean(LoadBalancerClient.class)
//創建了一個對應的LoadBalancerClient:RibbonLoadBalancerClient實例放入spring容器中管理
public LoadBalancerClient loadBalancerClient() {
return new RibbonLoadBalancerClient(springClientFactory());
}
}
10、將思路拉回主流程LoadBalancerInterceptor攔截器中
最終你會發現說,在LoadBalancerInterceptor攔截器裏,會將RestTemplate的方法和請求轉發給RibbonLoadBalancerClient.execute()方法去執行
總結:一張尋找LoadBalancerClient是如何完成實例化的流程圖