Ribbon源码学习(一)

220 阅读1分钟

一.入口发现

一般在构建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);
            };
		}
	}

其实以上的代码我们只需要关心两个核心的类, RestTemplateCustomizerLoadBalancerInterceptor

怕信息量太多,这里先整理下 流程图

我们知道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开始分析