Welcome to my GitHub
https://github.com/zq2599/blog_demos
Content: Classification and summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;
Previous review
- This article is the third article in Xinchen's "spring-cloud-square original" series. Let's quickly review the first two articles:
- "Understanding spring-cloud-square in five minutes" : It is clear what spring-cloud-square is
- "Spring-cloud-square development combat (full coverage of three types)" : Explain clearly how to use spring-cloud-square
- Next, in order to learn more about spring-cloud-square, I plan to read its source code. Are you interested in learning together?
Motivation for reading source code
- Let me first talk about why you want to see the spring-cloud-square source code
- Spring is a model of Java open source projects, and its source code is of high quality and reference value
- Compared with other spring projects, the source code of spring-cloud-square is pitiful. I spend the least time reading the source code of the spring project. I am very interested in this matter.
- Auto-assembly, interceptor, and automatic implementation of business interfaces. These technologies all appear in the spring-cloud-square project. After understanding and learning, they have a high reference value for their own projects.
Grasp the core direction
- In a project like spring-cloud-square that integrates multiple libraries, there are a lot of source code involved, and it is easy to fall into the details of one code after another (continuously expand the involved classes and source code), so here first Determine the core direction of this source code analysis:
- okhttp source code, only look at the key parts, skip the rest
- I just want to know why I can access the corresponding service by entering the service name when using spring-cloud-square-okhttp.jar
- The above is the main direction of reading the source code this time. When I fall into the details, this main direction will pull me back in time and continue to move towards the established goal.
Download source code
- The download address is: https://github.com/spring-cloud-incubator/spring-cloud-square, I chose the release version in the red box below to download:
- After the download is complete, unzip and open the source code with IDEA. The obtained project structure is as follows:
- Today, our goal is the <font color="blue">spring-cloud-square-okhttp</font> sub-project in the above picture. Read its source code and learn its essence!
Summary in advance
- As everyone knows, Xinchen's writing level is at the bottom of CSDN, and he likes nonsense, which makes many readers unable to stand it. Therefore, here is a summary in advance, and the essence of this article is directly presented. If you have limited time, or simply do not have the interest to learn more , You can leave directly after reading the summary, which is not without gain.....
- Summarize the source code of the entire project:
- The user of spring-cloud-square-okhttp.jar is a java application that needs to write code to instantiate OkHttpClient.Builder object
- OkHttpLoadBalancerAutoConfiguration configured in spring.factories will be scanned and instantiated by the spring framework
- OkHttpLoadBalancerInterceptor is instantiated in OkHttpLoadBalancerAutoConfiguration, and the LoadBalancerClient instance is passed to it
- OkHttpLoadBalancerAutoConfiguration instantiates the implementation of OkHttpClientBuilderCustomizer interface, which is a lambda expression, the function is to pass all Interceptors to the builder corresponding to the lambda expression
- OkHttpBuilderBeanPostProcessor is instantiated in OkHttpLoadBalancerAutoConfiguration. When the OkHttpClient.Builder object in step 1 is instantiated, OkHttpBuilderBeanPostProcessor will call the addInterceptor object of OkHttpClient.Builder and pass OkHttpLoadBalancerInterceptor to OkHttpClient.Builder
- When the business code is accessed remotely, the OkHttpClient object is created with OkHttpClient.Builder. At this time, OkHttpClient gets OkHttpLoadBalancerInterceptor. In remote access, the URL passed by the business code is the name of the remote service, but OkHttpLoadBalancerInterceptor will use LoadBalancerClient to remotely serve Replace the name with the corresponding IP and port, and then perform the real network request
- I heard that a picture is worth a thousand words, and Xinchen’s two knives’ drawing techniques are really not flattering, but I still insist on expressing the important steps in pictures, as shown below, I hope you will take a look:
- Next, if you still want to study and understand spring-cloud-square in depth, just enjoy the world of its source code with Xinchen.
Knowledge point supplement (OkHttpClient.Builder.addInterceptor)
- First of all, we must add an important knowledge point: What is the role of OkHttpClient.Builder.addInterceptor method?
- Looking at the source code is very simple, that is, put the interceptor into the collection <font color="blue">interceptors</font>:
public Builder addInterceptor(Interceptor interceptor) {
if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
interceptors.add(interceptor);
return this;
}
- The builder serves to instantiate OkHttpClient. Look at the OkHttpClient construction method and find that interceptors have been copied:
- When using OkHttpClient to access the network, getResponseWithInterceptorChain in the red box below is executed:
- Then there is the classic chain processing, all interceptors will be executed, the following figure shows how to construct and start the chain processing:
- Entering inside proceed, it can be seen that every time the proceed method is executed, an interceptor will be taken out and its intercept method will be called:
- Take the OkHttpLoadBalancerInterceptor of the spring-cloud-square framework as an example. The method in the red box in the figure below is <font color="red"> is extremely important </font>. After this line of code is executed, it will return to the previous figure. The proceed method continues to process the next interceptor:
- So far we can summarize: The function of the OkHttpClient.Builder.addInterceptor method is to pass in an Interceptor implementation class. When OkHttpClient executes a network request, the intercept method of the Interceptor will be executed. Please remember this summary. There will be great use later!
spring-cloud-square-okhttp
- spring-cloud-square provides three specific implementations. The first is a combination of <font color="blue">spring-cloud-loadbalancer + spring-cloud-square-okhttp</font>, and spring-cloud- Loadbalancer is another project that will not be developed in this article, so the first thing we look at is the source code of <font color="red">spring-cloud-square-okhttp</font>
- Open the project as shown below, I can only feel two words: <font color="blue">This is it? </font>
- Regarding the configuration file additional-spring-configuration-metadata.json, spring document , as shown in the red box below. The processor responsible for processing annotations will merge the content of additional-spring-configuration-metadata.json into the meta In the data file:
- Take a look at the content of additional-spring-configuration-metadata.json, as follows, the default value of the property <font color="blue">okhttp.loadbalancer.enabled</font> is defined as true:
{
"groups": [
],
"properties": [
{
"name": "okhttp.loadbalancer.enabled",
"type": "java.lang.Boolean",
"description": "Allows disabling OkHttp Spring Cloud LoadBalancer support.",
"defaultValue": "true"
}
]
}
- If you have written a custom starter library, then you must know that the entire spring-cloud-square-okhttp project should be viewed from the spring.factories file, which will determine which configuration classes to be instantiated:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.square.okhttp.loadbalancer.OkHttpLoadBalancerAutoConfiguration
- It can be seen that the configuration class OkHttpLoadBalancerAutoConfiguration will be instantiated. Let’s take a look at OkHttpLoadBalancerAutoConfiguration.java, as shown in the figure below. After a long series of analysis, we get a conclusion: OkHttpBuilderBeanPostProcessor is instantiated
- Look at OkHttpBuilderBeanPostProcessor.java, as shown in the figure below, focusing on the three key points in the red box:
- Recalling the "spring-cloud-square development combat (full coverage of three types)" , when we use spring-cloud-square-okhttp.jar, we have to write a configuration class to instantiate OkHttpClient.Builder , As shown below, so it can be seen: OkHttpBuilderBeanPostProcessor is prepared for the OkHttpClient.Builder instance we created. Simply put, after OkHttpClient.Builder is created, there is OkHttpBuilderBeanPostProcessor to pass OkHttpLoadBalancerInterceptor to 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();
}
}
- Have you suddenly realized it at this moment? It turns out that the so-called spring-cloud-square-okhttp actually requires the user to make an instance of OkHttpClient.Builder, and then spring-cloud-square-okhttp is responsible for plugging the OkHttpLoadBalancerInterceptor to the OkHttpClient.Builder instance. In this way, we are using When OkHttpClient makes remote calls, the intercept method of OkHttpLoadBalancerInterceptor will be executed!
- The last thing to look at is OkHttpLoadBalancerInterceptor. In fact, you are smart enough to guess its role at this moment. It holds an instance of LoadBalancerClient. Then when accessing the network, you can extract the service name in the URL and use LoadBalancerClient to find it. Corresponding service address, and OkHttpClient remote access can use this address, yes, that's it:
reward
- In fact, the core of the entire source code is to insert an Interceptor into OkHttpClient. This Interceptor can replace the service name with IP and address. The function is nothing more than that, but will the harvest stop here? This is a subjective question. Everyone’s gains are different. My biggest gains are the following two points:
- The chain processing of OkHttpClient is wonderful. The chain.proceed method is mandatory in Interceptor.intercept, which reminds me of the overlay processing logic in the decorator mode
- How to use <font color="blue">spring.factories + AutoConfig + BeanPostProcessor + SpringCloud LoadBalance</font> to work together, spring-cloud-square-okhttp is a lesson for me, especially the three constructors in OkHttpLoadBalancerAutoConfiguration The order of injection, people have a kind of urge to applaud, can I write such a concise and bright starter?
- So far, the spring-cloud-square spring-cloud-square-okhttp article of spring-cloud-square source code speed reading has been completed. On your way to learn spring, I hope this article can give you some reference
- The next challenge is the retrofit-related source code of spring-cloud-square. The amount of code will increase a lot, but why are you afraid of it? Xinchen original, will not disappoint your expectations!
You are not alone, Xinchen and original are with you all the way
- Java series
- Spring series
- Docker series
- kubernetes series
- Database + Middleware Series
- DevOps series
Welcome to pay attention to the public account: programmer Xin Chen
Search "Programmer Xin Chen" on WeChat, I am Xin Chen, and I look forward to traveling the Java world with you..
https://github.com/zq2599/blog_demos
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。