第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

Spring RestTemplate 源碼解析

標(biāo)簽:
SpringBoot
  • RestTemplate的概述
    spring 架构中,RestTemplate是客户端http请求的核心类,它使和服务端的请求更加简单,同时强化了RestFul的原理,它会处理http请求的连接,使应用代码只需提供url和参数,解析结果就可以了。
    RestTemplate默认是依赖于标准sdk 工具去建立连接,你可以通过setRequestFactory方法用其它的http库来替换,比如apache httpComponents,Netty 和OkHttp

  • RestTemplate的类图


    webp

    RestTemplate类图

  1. HttpAccessor 类
    RestTemplate的基类,是一个抽象类,提供了一些公共的属性,如 ClientHttpRequestFactory,ClientHttpRequestFactory 是clientHttpRequest的工厂类,通过 createRequest 来创建http请求的方法

  2. InterceptingHttpAccessor 类
    这个是 HttpAccessor的一个抽象子类,多增加了 请求拦截器相关的属性,ClientHttpRequestInterceptor,而这个ClientHttpRequestInterceptor是 spring cloud中各种服务治理的关键,如客户端负载均衡,链路跟踪等

  • RestTemplate的doExecute 方法

该方法是RestTemplate的核心方法

webp

image.png


它主要有四个参数

  1. url 请求的http 地址

  2. method http请求的method

  3. requestCallback 是一个接口Request Callback

  4. responseExtractor 也是一个接口 ResponseExtractor
    我们来设想下,如果我们自己设计一个封装http请求的组件,一定也会遵守开闭原则,开放出可以让用户自定义的接口,那第三,第四个参数就是这个作用的。
    来看下,spring 里默认是怎么做的,首先看下这两个接口的定义

public interface RequestCallback {    /**
     * Gets called by {@link RestTemplate#execute} with an opened {@code ClientHttpRequest}.
     * Does not need to care about closing the request or about handling errors:
     * this will all be handled by the {@code RestTemplate}.
     * @param request the active HTTP request
     * @throws IOException in case of I/O errors
     */
    void doWithRequest(ClientHttpRequest request) throws IOException;

}
public interface ResponseExtractor<T> {    /**
     * Extract data from the given {@code ClientHttpResponse} and return it.
     * @param response the HTTP response
     * @return the extracted data
     * @throws IOException in case of I/O errors
     */
    T extractData(ClientHttpResponse response) throws IOException;

}

很明显,这两个接口分别是在请求前,ClientHttpRequest请求前会作回调,而在请求结束后,又会调用ResponseExtractor去作请求结果解析的动作
再来看下方法createRequest

protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
        ClientHttpRequest request = getRequestFactory().createRequest(url, method);        if (logger.isDebugEnabled()) {
            logger.debug("Created " + method.name() + " request for \"" + url + "\"");
        }        return request;
    }

getRequestFactory()InterceptingHttpAccessor 中被重载了

@Override
    public ClientHttpRequestFactory getRequestFactory() {
        ClientHttpRequestFactory delegate = super.getRequestFactory();        if (!CollectionUtils.isEmpty(getInterceptors())) {            return new InterceptingClientHttpRequestFactory(delegate, getInterceptors());
        }        else {            return delegate;
        }
    }

如果有设置拦截器,则返回的是一个InterceptingClientHttpRequestFactory类,而这个类创建的是

@Override
    protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) {        return new InterceptingClientHttpRequest(requestFactory, this.interceptors, uri, httpMethod);
    }

Resttemplate 调用 的ClientHttpRequest.execute() 方法,其实就是InterceptingClientHttpRequest的方法,再来看下这个类的实现吧

@Override
    protected final ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
        InterceptingRequestExecution requestExecution = new InterceptingRequestExecution();        return requestExecution.execute(this, bufferedOutput);
    }

最终是通过InterceptingRequestExecution类来完成最终的调用

@Override
        public ClientHttpResponse execute(HttpRequest request, final byte[] body) throws IOException {            if (this.iterator.hasNext()) {
                ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();                return nextInterceptor.intercept(request, body, this);
            }            else {
                ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());                for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
                    List<String> values = entry.getValue();                    for (String value : values) {
                        delegate.getHeaders().add(entry.getKey(), value);
                    }
                }                if (body.length > 0) {                    if (delegate instanceof StreamingHttpOutputMessage) {
                        StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) delegate;
                        streamingOutputMessage.setBody(new StreamingHttpOutputMessage.Body() {                            @Override
                            public void writeTo(final OutputStream outputStream) throws IOException {
                                StreamUtils.copy(body, outputStream);
                            }
                        });
                    }                    else {
                        StreamUtils.copy(body, delegate.getBody());
                    }
                }                return delegate.execute();
            }
        }

从上面的代码可以很清晰的看到是怎么调用ClientHttpRequestInterceptor



作者:David_jim
链接:https://www.jianshu.com/p/e771e387b548


點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消