webclient對(duì)reactor-netty的封裝

本文主要研究一下spring 5的WebClient對(duì)reactor-netty的HttpClient的封裝

DefaultWebClientBuilder

spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java

    @Override
    public WebClient build() {
        ExchangeFunction exchange = initExchangeFunction();
        ExchangeFunction filteredExchange = (this.filters != null ? this.filters.stream()
                .reduce(ExchangeFilterFunction::andThen)
                .map(filter -> filter.apply(exchange))
                .orElse(exchange) : exchange);
        return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
                unmodifiableCopy(this.defaultHeaders), unmodifiableCopy(this.defaultCookies),
                new DefaultWebClientBuilder(this));
    }   

這里的build調(diào)用了initExchangeFunction方法

    private ExchangeFunction initExchangeFunction() {
        if (this.exchangeFunction != null) {
            return this.exchangeFunction;
        }
        else if (this.connector != null) {
            return ExchangeFunctions.create(this.connector, this.exchangeStrategies);
        }

        else {
            return ExchangeFunctions.create(new ReactorClientHttpConnector(), this.exchangeStrategies);
        }
    }

這里new了一個(gè)ReactorClientHttpConnector

ReactorClientHttpConnector

spring-web-5.0.2.RELEASE-sources.jar!/org/springframework/http/client/reactive/ReactorClientHttpConnector.java

    /**
     * Create a Reactor Netty {@link ClientHttpConnector}
     * with default {@link ClientOptions} and HTTP compression support enabled.
     */
    public ReactorClientHttpConnector() {
        this.httpClient = HttpClient.builder()
                .options(options -> options.compression(true))
                .build();
    }

可以看到這個(gè)構(gòu)造器使用了reactor/ipc/netty/http/client/HttpClient

DefaultWebClient

spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/DefaultWebClient.java

    @Override
    public RequestHeadersUriSpec<?> get() {
        return methodInternal(HttpMethod.GET);
    }

    @Override
    public RequestHeadersUriSpec<?> head() {
        return methodInternal(HttpMethod.HEAD);
    }

    @Override
    public RequestBodyUriSpec post() {
        return methodInternal(HttpMethod.POST);
    }

    @Override
    public RequestBodyUriSpec put() {
        return methodInternal(HttpMethod.PUT);
    }

    @Override
    public RequestBodyUriSpec patch() {
        return methodInternal(HttpMethod.PATCH);
    }

    @Override
    public RequestHeadersUriSpec<?> delete() {
        return methodInternal(HttpMethod.DELETE);
    }

    @Override
    public RequestHeadersUriSpec<?> options() {
        return methodInternal(HttpMethod.OPTIONS);
    }

    @Override
    public RequestBodyUriSpec method(HttpMethod httpMethod) {
        return methodInternal(httpMethod);
    }

    @SuppressWarnings("unchecked")
    private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) {
        return new DefaultRequestBodyUriSpec(httpMethod);
    }

DefaultWebClient主要對(duì)GET、HEAD登淘、POST缸榛、PUT扼脐、PATCH霹粥、DELETE、OPTIONS方法封裝返回RequestHeadersUriSpec或者RequestBodyUriSpec

        @Override
        public Mono<ClientResponse> exchange() {
            ClientRequest request = (this.inserter != null ?
                    initRequestBuilder().body(this.inserter).build() :
                    initRequestBuilder().build());
            return exchangeFunction.exchange(request).switchIfEmpty(NO_HTTP_CLIENT_RESPONSE_ERROR);
        }

最后在exchange方法里頭封裝了對(duì)exchangeFunction的調(diào)用损同,這里的switchIfEmpty返回的是reactor.core.publisher.MonoSwitchIfEmpty<ClientResponse>

spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/ExchangeFunctions.java

        public Mono<ClientResponse> exchange(ClientRequest request) {
            Assert.notNull(request, "'request' must not be null");
            return this.connector
                    .connect(request.method(), request.url(),
                            clientHttpRequest -> request.writeTo(clientHttpRequest, this.strategies))
                    .log("org.springframework.web.reactive.function.client", Level.FINE)
                    .map(clientHttpResponse -> new DefaultClientResponse(clientHttpResponse,
                            this.strategies));
        }

這里調(diào)用了ReactorClientHttpConnector的connect方法

spring-web-5.0.2.RELEASE-sources.jar!/org/springframework/http/client/reactive/ReactorClientHttpConnector.java

    public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
            Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {

        if (!uri.isAbsolute()) {
            return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri));
        }

        return this.httpClient
                .request(adaptHttpMethod(method),
                        uri.toString(),
                        request -> requestCallback.apply(adaptRequest(method, uri, request)))
                .map(this::adaptResponse);
    }

connect方法最后調(diào)用的reactor-netty的HttpClient的request方法帐偎。

小結(jié)

spring 5的webflux部分主要基于reactor項(xiàng)目來(lái)的,WebClient也是基于reactor-netty來(lái)實(shí)現(xiàn)御雕,主要是封裝了一些UriSpec及其他便利方法矢沿。

接口見(jiàn)spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/WebClient.java

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酸纲,隨后出現(xiàn)的幾起案子捣鲸,更是在濱河造成了極大的恐慌,老刑警劉巖闽坡,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栽惶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疾嗅,警方通過(guò)查閱死者的電腦和手機(jī)外厂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)代承,“玉大人汁蝶,你說(shuō)我怎么就攤上這事÷坫玻” “怎么了掖棉?”我有些...
    開(kāi)封第一講書人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)膀估。 經(jīng)常有香客問(wèn)我幔亥,道長(zhǎng),這世上最難降的妖魔是什么察纯? 我笑而不...
    開(kāi)封第一講書人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任帕棉,我火速辦了婚禮,結(jié)果婚禮上捐寥,老公的妹妹穿的比我還像新娘笤昨。我一直安慰自己,他們只是感情好握恳,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布瞒窒。 她就那樣靜靜地躺著,像睡著了一般乡洼。 火紅的嫁衣襯著肌膚如雪崇裁。 梳的紋絲不亂的頭發(fā)上匕坯,一...
    開(kāi)封第一講書人閱讀 52,793評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音拔稳,去河邊找鬼葛峻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巴比,可吹牛的內(nèi)容都是我干的术奖。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼轻绞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼采记!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起政勃,我...
    開(kāi)封第一講書人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤唧龄,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后奸远,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體既棺,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年懒叛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丸冕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芍瑞,死狀恐怖晨仑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拆檬,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布妥凳,位于F島的核電站竟贯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏逝钥。R本人自食惡果不足惜屑那,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艘款。 院中可真熱鬧持际,春花似錦、人聲如沸哗咆。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晌柬。三九已至姥份,卻和暖如春郭脂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澈歉。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工展鸡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人埃难。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓莹弊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親涡尘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忍弛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容