RestTemplate浅析

用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,留下了扩展接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值