loadbalancer
loadbalancer源码学习
代码入口
restTemplate.getForObject("http://service/getUser",String.class);
restTemplate. getForObject
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
//主要看execute这个方法
return this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, (Object[])uriVariables);
}
restTemplate.execute
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {
URI expanded = this.getUriTemplateHandler().expand(url, uriVariables);
//这里又调用了doExecite
return this.doExecute(expanded, method, requestCallback, responseExtractor);
}
restTemplate.doExecute
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
Object var14;
try {
//createRequest构建客服端请求的一个方法//调用父类HttpAccessor的createRequest
ClientHttpRequest request = this.createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
this.handleResponse(url, method, response);
var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;
} catch (IOException var12) {
String resource = url.toString();
String query = url.getRawQuery();
resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;
throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + var12.getMessage(), var12);
} finally {
if (response != null) {
response.close();
}
}
return var14;
}
HttpAccessor. createRequest
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
//createRequest调用的是InterceptingHttpAccessor中的getRequestFactory方法
//因为InterceptingHttpAccessor继承了HttpAccessor这个类,重写了getRequestFactory方法。
ClientHttpRequest request = this.getRequestFactory().createRequest(url, method);
this.initialize(request);
if (this.logger.isDebugEnabled()) {
this.logger.debug("HTTP " + method.name() + " " + url);
}
return request;
}
这里是RestTemplate的类关系图
InterceptingHttpAccessor.getRequestFactory
public ClientHttpRequestFactory getRequestFactory() {
List<ClientHttpRequestInterceptor> interceptors = this.getInterceptors();
if (!CollectionUtils.isEmpty(interceptors)) {
ClientHttpRequestFactory factory = this.interceptingRequestFactory;
if (factory == null) {
factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);
this.interceptingRequestFactory = (ClientHttpRequestFactory)factory;
}
return (ClientHttpRequestFactory)factory;
} else {
return super.getRequestFactory();
}
}
LoadBalancerAutoConfiguration.RestTemplateCustomizer
上面的interceptors 是在LoadBalancer初始化的时候通过LoadBalancerAutoConfiguration这个配置类注入进来的
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(final RetryLoadBalancerInterceptor loadBalancerInterceptor) {
return (restTemplate) -> {
List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());
//这里注入loadBalancerInterceptor
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
InterceptingClientHttpRequestFactory.createRequest
protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) {
//这里返回注入的interceptors是上面注入的loadBalancerInterceptor
return new InterceptingClientHttpRequest(requestFactory, this.interceptors, uri, httpMethod);
}
所以,再回到createRequest方法中,getRequestFactory()方法返回的是
InterceptingClientHttpRequestFactory,而createRequest方法,最终返回的是
InterceptingClientHttpRequest。
RestTemplate.doExecute
继续跳回到RestTemplate.doExecute方法,最终会调用request.execute。
response = request.execute();