一.入口发现
一般在构建Ribbon的RestTemplate通过这么构建
点进 @LoadBalanced 注解,在其所在位置的JAR包中发现了一个LoadBalancerAutoConfiguration类。
根据经验,其实boot的自动装配逻辑就是依靠这个 XXAutoConfiguration
OK,下一步就是进入LoadBalancerAutoConfiguration这个类,下面就开始分析LoadBalancerAutoConfiguration 这个类
二.LoadBalancerAutoConfiguration 源码分析
上代码!!!
@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {
// 此处省略很多无用代码
@Configuration
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig {
@Bean
public LoadBalancerInterceptor ribbonInterceptor(
LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(
final LoadBalancerInterceptor loadBalancerInterceptor) {
return restTemplate -> {
List<ClientHttpRequestInterceptor> list = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
其实以上的代码我们只需要关心两个核心的类, RestTemplateCustomizer 和 LoadBalancerInterceptor
怕信息量太多,这里先整理下 流程图
我们知道LoadBalancerInterceptor是一个拦截器,而RestTemplateCustomizer就是对它进行了相关的封装。
restTemplate.getForObject(..)
连蒙带猜,ribbon底层一定是利用LoadBalancerInterceptor这个拦截器对restTemplate进行了封装。 OK,现在开始分析LoadBalancerInterceptor
三.LoadBalancerInterceptor
如上面分析,所有的请求都会进入LoadBalancerInterceptor, 然后会调用intercept这个方法
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
// 通过构造函数进行赋值
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
// originalUri 就是请求的URI
final URI originalUri = request.getURI();
// serviceName 就是对应的服务名
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
以上总结下来就是拿到URI请求的地址和serviceName服务名,并且拿到以上的信息,利用LoadBalancerClient 进行http调用。 流程图如下:
下一章将从LoadBalancerClient开始分析