用RestTemplate的getForObject方法,分析一下restTemplate的执行流程
1、整体执行流程
//org.springframework.web.client.RestTemplate#getForObject
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
//这里生成一个RestTemplate.AcceptHeaderRequestCallback,是个内部类
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
//生成response 转换器
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
//执行方法
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
//org.springframework.web.client.RestTemplate#execute
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {
//getUriTemplateHandler() 返回 UriTemplateHandler,其在restTemplate构造器初始化
//构建URI
URI expanded = getUriTemplateHandler().expand(url, uriVariables);
//执行
return doExecute(expanded, method, requestCallback, responseExtractor);
}
//org.springframework.web.client.RestTemplate#execute
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;
try {
//根据配置创建request对象
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
//执行请求
response = request.execute();
//处理结果
handleResponse(url, method, response);
//返回,并处理结果,转换对象
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
2、创建request
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
//getRequestFactory() 创建对应的工厂
//会根据配置创建具体类型的request,其中包括RibbonClientHttpRequestFactory
ClientHttpRequest request = getRequestFactory().createRequest(url, method);
initialize(request);
if (logger.isDebugEnabled()) {
logger.debug("HTTP " + method.name() + " " + url);
}
return request;
}
类继承关系
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations
public abstract class InterceptingHttpAccessor extends HttpAccessor
2.1、获取requestFactory
如果有interceptor 则创建InterceptingClientHttpRequestFactory,否则创建SimpleClientHttpRequestFactory
interceptor 这里是一个扩展点
//InterceptingHttpAccessor#getRequestFactory
public ClientHttpRequestFactory getRequestFactory() {
List<ClientHttpRequestInterceptor> interceptors = getInterceptors();
if (!CollectionUtils.isEmpty(interceptors)) {
ClientHttpRequestFactory factory = this.interceptingRequestFactory;
if (factory == null) {
factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);
this.interceptingRequestFactory = factory;
}
return factory;
}
else {
return super.getRequestFactory();
}
}
//HttpAccessor#getRequestFactory
//private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
public ClientHttpRequestFactory getRequestFactory() {
return this.requestFactory;
}
3、执行请求
//org.springframework.http.client.AbstractClientHttpRequest#execute
public final ClientHttpResponse execute() throws IOException {
assertNotExecuted();
ClientHttpResponse result = executeInternal(this.headers);
this.executed = true;
return result;
}
//AbstractBufferingClientHttpRequest#executeInternal
protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException {
byte[] bytes = this.bufferedOutput.toByteArray();
if (headers.getContentLength() < 0) {
headers.setContentLength(bytes.length);
}
ClientHttpResponse result = executeInternal(headers, bytes);
this.bufferedOutput = new ByteArrayOutputStream(0);
return result;
}
3.1、SimpleBufferingClientHttpRequest#executeInternal
//SimpleBufferingClientHttpRequest#executeInternal
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
addHeaders(this.connection, headers);
// JDK <1.8 doesn't support getOutputStream with HTTP DELETE
if (getMethod() == HttpMethod.DELETE && bufferedOutput.length == 0) {
this.connection.setDoOutput(false);
}
if (this.connection.getDoOutput() && this.outputStreaming) {
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
}
this.connection.connect();
if (this.connection.getDoOutput()) {
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
}
else {
// Immediately trigger the request in a no-output scenario as well
this.connection.getResponseCode();
}
return new SimpleClientHttpResponse(this.connection);
}
3.2、InterceptingClientHttpRequest#executeInternal
//org.springframework.http.client.InterceptingClientHttpRequest#executeInternal
protected final ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
InterceptingRequestExecution requestExecution = new InterceptingRequestExecution();
return requestExecution.execute(this, bufferedOutput);
}
//InterceptingClientHttpRequest.InterceptingRequestExecution#execute
public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {
//有Interceptor
if (this.iterator.hasNext()) {
ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();
return nextInterceptor.intercept(request, body, this);
}
//没有interceptor,执行
else {
HttpMethod method = request.getMethod();
Assert.state(method != null, "No standard HTTP method");
ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), method);
request.getHeaders().forEach((key, value) -> delegate.getHeaders().addAll(key, value));
if (body.length > 0) {
if (delegate instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) delegate;
streamingOutputMessage.setBody(outputStream -> StreamUtils.copy(body, outputStream));
}
else {
StreamUtils.copy(body, delegate.getBody());
}
}
return delegate.execute();
}
}
4、interceptors
//InterceptingHttpAccessor
private final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
//RestTemplate继承自该类,因此可以用restTemplate调这个方法添加interceptor
public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) {
Assert.noNullElements(interceptors, "'interceptors' must not contain null elements");
// Take getInterceptors() List as-is when passed in here
if (this.interceptors != interceptors) {
this.interceptors.clear();
this.interceptors.addAll(interceptors);
AnnotationAwareOrderComparator.sort(this.interceptors);
}
}
RestTemplate 利用 父类中的 interceptors,留下了扩展接口