共计 5869 个字符,预计需要花费 15 分钟才能阅读完成。
欢送拜访我的 GitHub
https://github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,波及 Java、Docker、Kubernetes、DevOPS 等;
前文回顾
- 本篇是欣宸《spring-cloud-square 原创》系列的第三篇,咱们疾速回顾一下后面两篇:
- 《五分钟搞懂 spring-cloud-square》:说分明了 spring-cloud-square 是什么
- 《spring-cloud-square 开发实战 (三种类型全笼罩)》:说分明了 spring-cloud-square 怎么用
- 接下来,为了深刻理解 spring-cloud-square,我打算读它的源码,爱学习的您有没有趣味一起呢?
浏览源码的动机
- 先说一下为什么要去看 spring-cloud-square 源码
- spring 是 java 开源我的项目的榜样,它的源码具备很高的品质和参考价值
- 和其余 spring 我的项目相比,spring-cloud-square 的源码少得可怜,花起码的工夫浏览 spring 我的项目的源码,这事儿我挺有趣味
- 主动拆卸、拦截器、业务接口主动实现,这些技术都呈现在 spring-cloud-square 我的项目中,看懂了学会了,对本人的我的项目有很高的参考价值
把握外围方向
- 在 spring-cloud-square 这种集成了多个库的我的项目中,波及的源码是很多的,很容易陷入一个又一个代码的细节中(不停的开展波及的类和源码),因而,这里先确定本次源码剖析的外围方向:
- okhttp 源码,只看要害局部,其余一律跳过
- 只想晓得在应用 spring-cloud-square-okhttp.jar 的时候,为何输出服务名就能拜访到对应的服务
- 以上就是这次浏览源码的主方向,在陷入细节时,这个主方向会及时将我拉回来,持续朝既定目标后退
下载源码
- 下载地址是:https://github.com/spring-clo…,我选则了下图红框中的 release 版下载:
- 下载结束后解压,用 IDEA 关上源码,失去的我的项目构造如下:
- 明天,咱们的指标就是上图的 <font color=”blue”>spring-cloud-square-okhttp</font> 子工程,读它源码,学它精华!
提前小结
- 总所周知,欣宸文笔程度在 CSDN 垫底,还喜爱废话,导致很多读者都看不下去,因而这里提前做个小结,将本篇精髓间接奉上,如果您工夫无限,或者罗唆没趣味深刻理解,能够看完小结后间接来到,也不算毫无播种 …..
- 将整个工程源码串起来小结:
- spring-cloud-square-okhttp.jar 的使用者是个 java 利用,该利用要写代码实例化 OkHttpClient.Builder 对象
- spring.factories 中配置的 OkHttpLoadBalancerAutoConfiguration,会被 spring 框架扫到并实例化
- OkHttpLoadBalancerAutoConfiguration 中实例化了 OkHttpLoadBalancerInterceptor,并将 LoadBalancerClient 实例传给它
- OkHttpLoadBalancerAutoConfiguration 中实例化了 OkHttpClientBuilderCustomizer 接口的实现,这外面是个 lambda 表达式,性能是将所有 Interceptor 传给 lambda 表达式对应的 builder
- OkHttpLoadBalancerAutoConfiguration 中实例化了 OkHttpBuilderBeanPostProcessor,当步骤 1 中的 OkHttpClient.Builder 对象被实例化后,OkHttpBuilderBeanPostProcessor 会调用 OkHttpClient.Builder 的 addInterceptor 对象,将 OkHttpLoadBalancerInterceptor 传给 OkHttpClient.Builder
- 业务代码近程拜访的时候,用 OkHttpClient.Builder 创立 OkHttpClient 对象,此时的 OkHttpClient 就失去了 OkHttpLoadBalancerInterceptor,在近程拜访时,业务代码传入的 URL 中是近程服务的名字,然而 OkHttpLoadBalancerInterceptor 会借助 LoadBalancerClient 将近程服务的名字替换成对应的 IP 和端口,而后再执行真正的网络申请
- 据说一图胜千言,欣宸二把刀的作图技术切实不敢恭维,但还是保持把重要步骤用图表达出来了,如下所示,心愿您能将就着看:
- 接下来,如果您还想深入研究和理解 spring-cloud-square,就随欣宸一起畅游它的源码世界吧
知识点补充(OkHttpClient.Builder.addInterceptor)
- 首先要补充一个重要知识点:OkHttpClient.Builder.addInterceptor 办法的作用是什么?
- 看源码很简略,就是将 interceptor 放入汇合 <font color=”blue”>interceptors</font> 中:
public Builder addInterceptor(Interceptor interceptor) {if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
interceptors.add(interceptor);
return this;
}
- builder 是为实例化 OkHttpClient 服务的,去看 OkHttpClient 的构造方法,发现 interceptors 被复制过去了:
- 在应用 OkHttpClient 拜访网络的时候,会执行下图红框中的 getResponseWithInterceptorChain:
- 而后就是经典的链式解决了,所有的 interceptor 都会被执行,下图展现了如何结构和启动链式解决:
- 进入 proceed 外部,可见每次执行 proceed 办法,都会取出一个 interceptor,调用其 intercept 办法:
- 以 spring-cloud-square 框架的 OkHttpLoadBalancerInterceptor 为例,下图红框中的办法 <font color=”red”> 极为重要 </font>,这行代码执行后,会回到上一幅图中的 proceed 办法,持续解决下一个 interceptor:
- 至此能够小结了:OkHttpClient.Builder.addInterceptor 办法的作用,是传入一个 Interceptor 实现类,在 OkHttpClient 执行网络申请的时候,该 Interceptor 的 intercept 办法会被执行,请记住这个小结,前面有大用处!
spring-cloud-square-okhttp
- spring-cloud-square 提供了三种具体的实现,第一种是 <font color=”blue”>spring-cloud-loadbalancer + spring-cloud-square-okhttp</font> 的组合,而 spring-cloud-loadbalancer 是另一个我的项目不在此文中开展,因而,咱们最先看的就是 <font color=”red”>spring-cloud-square-okhttp</font> 的源码了
- 关上我的项目如下图,我只能感叹两个字:<font color=”blue”> 就这?</font>
- 对于配置文件 additional-spring-configuration-metadata.json,在 spring 文档中有提到,如下图红框,负责解决注解的处理器会将 additional-spring-configuration-metadata.json 的内容合并到元数据文件中去:
- 看看 additional-spring-configuration-metadata.json 的内容,如下,定义了属性 <font color=”blue”>okhttp.loadbalancer.enabled</font> 的默认值为 true:
{"groups": [],
"properties": [
{
"name": "okhttp.loadbalancer.enabled",
"type": "java.lang.Boolean",
"description": "Allows disabling OkHttp Spring Cloud LoadBalancer support.",
"defaultValue": "true"
}
]
}
- 如果您写过自定义 starter 库,那么您肯定晓得,整个 spring-cloud-square-okhttp 我的项目应该从 spring.factories 文件看起,这外面会确定那些配置类要被实例化:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.square.okhttp.loadbalancer.OkHttpLoadBalancerAutoConfiguration
- 可见配置类 OkHttpLoadBalancerAutoConfiguration 会被实例化,咱们去看看 OkHttpLoadBalancerAutoConfiguration.java,如下图,通过一长串剖析失去一个论断:OkHttpBuilderBeanPostProcessor 被实例化了
- 再看 OkHttpBuilderBeanPostProcessor.java,如下图,重点关注红框中的三个关键点:
- 回顾《spring-cloud-square 开发实战 (三种类型全笼罩)》中的代码,咱们在应用 spring-cloud-square-okhttp.jar 的时候,要本人写一个配置类来实例化 OkHttpClient.Builder,如下所示,因而可见:OkHttpBuilderBeanPostProcessor 就是给咱们创立的 OkHttpClient.Builder 实例筹备的,简略的说,就是 OkHttpClient.Builder 在创立后,就有 OkHttpBuilderBeanPostProcessor 将 OkHttpLoadBalancerInterceptor 传递给 OkHttpClient.Builder:
package com.bolingcavalry.consumer;
import okhttp3.OkHttpClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
class OkHttpClientConfig{
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {return new OkHttpClient.Builder();
}
}
- 此刻的您有没有豁然开朗呢?原来如此啊,所谓 spring-cloud-square-okhttp,其实就是要求用户本人做一个 OkHttpClient.Builder 实例,而后 spring-cloud-square-okhttp 负责将 OkHttpLoadBalancerInterceptor 塞给 OkHttpClient.Builder 实例,如此一来,咱们在应用 OkHttpClient 做近程调用的时候,OkHttpLoadBalancerInterceptor 的 intercept 办法就会被执行了!
- 最初要看的就是 OkHttpLoadBalancerInterceptor 了,其实聪慧的您此刻曾经猜到它的作用了,它持有了 LoadBalancerClient 实例,那么在拜访网络的时候,就能够将 URL 中的服务名抠出来,用 LoadBalancerClient 查到对应的服务地址,而后 OkHttpClient 近程拜访能够用这个地址了,没错,就是如此:
播种
- 其实整个源码的外围就是给 OkHttpClient 塞进去一个 Interceptor,这个 Interceptor 能够将服务名替换成 IP 和地址,性能仅此而已,然而播种是否会止步于此呢?这是个主观问题,各人的播种都不一样吧,我这最大的播种有以下两点:
- OkHttpClient 的链式解决很精彩,Interceptor.intercept 中强制要求执行 chain.proceed 办法,让我想起了装璜者模式中的叠加解决逻辑
- 如何用 <font color=”blue”>spring.factories + AutoConfig + BeanPostProcessor + SpringCloud LoadBalance</font> 协同作战,spring-cloud-square-okhttp 算是给我上了一课,尤其是 OkHttpLoadBalancerAutoConfiguration 中三个结构器的程序注入,让人有种鼓掌叫好的激动,我能写出这样简洁明快的 starter 吗?
- 至此,spring-cloud-square 源码速读的 spring-cloud-squarespring-cloud-square-okhttp 篇曾经实现了,在您学习 spring 的路线上,心愿本文可能带给您一些参考
- 接下来要挑战的是 spring-cloud-square 的 retrofit 相干源码,代码量会减少很多,然而,何惧之有?欣宸原创,必不会辜负您的期待!
你不孤独,欣宸原创一路相伴
- Java 系列
- Spring 系列
- Docker 系列
- kubernetes 系列
- 数据库 + 中间件系列
- DevOps 系列
欢送关注公众号:程序员欣宸
微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游 Java 世界..
https://github.com/zq2599/blog_demos
正文完