Feign
FeignClient注解分析
@Target(ElementType.TYPE)修飾始衅,表示FeignClient注解的作用目標(biāo)在接口上汛闸,簡(jiǎn)單的介紹下各個(gè)屬性涮俄。value(), name()都是一樣的,都是定義的serviceId孕锄。uri()直接寫硬編碼的地址苞尝,一般用來調(diào)試用,decode404()針對(duì)返回結(jié)果404被解碼或者拋異常轴脐。configuration()為feign的配置類,默認(rèn)的配置類為FeignClientsConfiguration恬涧,fallback()為相關(guān)的熔斷類碴巾。
FeignClient運(yùn)行原理
主程序上添加@EnableFeignClients這個(gè)注解,啟動(dòng)時(shí)會(huì)自動(dòng)加載feign的相關(guān)配置提揍,并且掃描帶有@FeignClient的類煮仇,源碼在FeignClientsRegistrar類里
registerFeignClients這個(gè)方法掃描所有帶有@FeignClient注解的類
獲取到相關(guān)的基礎(chǔ)配置刨仑,最后賦值給BeanDefinitionBuilder绞呈,得到BeanDefinition间景,注入到IOC容器中。之后通過JDK代理圾亏,在調(diào)用feign client接口方法的時(shí)候封拧,就會(huì)被攔截,源碼在ReflectiveFeign曹铃。
通過jdk代理新建個(gè)實(shí)例陕见。在SynchronousMethodHandler進(jìn)行攔截味抖,根據(jù)參數(shù)生成一個(gè)基于http的RequestTemplate對(duì)象。
調(diào)用了executeAndDecode()這個(gè)方法忍坷,這個(gè)方法是根據(jù)參數(shù)生成一個(gè)request請(qǐng)求對(duì)象佩研,通過http client獲取response。
feign的負(fù)載均衡
查看一下LoadBalancerFeignClient嘉抒,其中的execute方法袍暴。
代碼中執(zhí)行了executeWithLoadBalancer方法政模,這個(gè)方法里又調(diào)用了LoadBalancerCommand類中的submit方法
submit方法又調(diào)用了selectServer這個(gè)方法
由該方法進(jìn)行選擇負(fù)載均衡的方法岗宣,最終負(fù)載均衡交給loadBalancerContext來處理,也就是ribbon淋样。
Server server = LoadBalancerCommand.this.loadBalancerContext.getServerFromLoadBalancer(LoadBalancerCommand.this.loadBalancerURI, LoadBalancerCommand.this.loadBalancerKey);
feign的工作流程總結(jié)如下:
1-主程序啟動(dòng)掃描EnableFeignClients這個(gè)注解耗式。
2-接下來掃描FeignClient注解。
3-在調(diào)用有FeignClient注解標(biāo)注的接口趁猴,開啟jdk代理刊咳,生成一個(gè)requestTemplate對(duì)象。
4-這個(gè)request請(qǐng)求交給Client去處理儡司,去判斷使用HttpClient娱挨,OkHttp 還是默認(rèn)的HttpURLConnection框架。
5-client類被封裝到LoadBalancerClient類里捕犬,通過ribbon實(shí)現(xiàn)負(fù)載均衡跷坝。