Project Reactor:OptimizableOperator 原理

前言

通常來說在響應(yīng)式編程中 Publisher 的創(chuàng)建到真正的訂閱者中間會經(jīng)過許多的響應(yīng)式操作符,而大部分的操作符其實都是 OptimizableOperator 的實現(xiàn)驾霜。

隨便舉幾個例子案训,例如:map,flatMap粪糙,filter强霎,doOnNext 等等∪馗裕基本上所有對上游數(shù)據(jù)做處理的函數(shù)都實現(xiàn)了 OptimizableOperator

準(zhǔn)備工作

你需要對 Reactor 或者響應(yīng)式編程有一定了解

推薦閱讀:
「響應(yīng)式編程入門之 Project Reactor」

OptimizableOperator

OptimizableOperator

首先 OptimizableOperator 繼承了 CorePublisher城舞,這沒什么可說的轩触,因為不管是使用 Mono 還是 Flux 執(zhí)行完任何操作之后返回的依舊是一個 Publisher

下面我們來看下 OptimizableOperator 的核心方法,先來簡單說下椿争,后邊會結(jié)合源碼來詳細(xì)理解

OptimizableOperator.subscribeOrReturn

該方法有兩種方式實現(xiàn)

  1. 返回一個 CoreSubscriber,返回的訂閱者包裝了下游的實際訂閱者
  1. 返回 null
    當(dāng)選擇這種實現(xiàn)方式時熟嫩,當(dāng)前 OptimizableOperator 自行消費真正的 Publisher秦踪。將自己作為下游 Subscriber 的發(fā)布者

這兩種實現(xiàn)方式有什么區(qū)別呢?第一種方式僅僅是作為一個消費者訂閱掸茅。而第二種方式椅邓,Operator 相當(dāng)于翻身農(nóng)奴把歌唱了,自己當(dāng)上了 Publisher昧狮,能做的事情比一種方式更多

OptimizableOperator.source

返回當(dāng)前 OptimizableOperator 的上游(上游可能還是一個 OptimizableOperator)

OptimizableOperator.nextOptimizableSource

返回鏈中的下一個 OptimizableOperator(如果上游是 OptimizableOperator 則返回景馁,否則返回 null)

InternalMonoOperator

我們來通過 InternalMonoOperator 來理解一下上述的幾個方法

InternalMonoOperator

InternalMonoOperator 構(gòu)造方法

InternalMonoOperator 是所有 Mono 操作符的父類,在執(zhí)行操作符動作之前都會先構(gòu)建操作符對象逗鸣,最終會調(diào)用到 InternalMonoOperator 構(gòu)造方法合住。

  1. 入?yún)?source 為當(dāng)前操作符的上游,
  2. super(source) 內(nèi)部實現(xiàn)是將上游賦值給成員變量 source
  3. 如果上游同樣也是操作符撒璧,還會將其賦值給 optimizableOperator

subscribe

當(dāng)最后一個操作符被訂閱時會執(zhí)行如下邏輯透葛。看似很難讀卿樱,其實和上面我們講的是一樣的僚害,下面一起來分析下

public final void subscribe(CoreSubscriber<? super O> subscriber) {
    // 將當(dāng)前對象賦值給 operator
    OptimizableOperator operator = this;
    try {
        while (true) {
            // 調(diào)用操作符的 subscribeOrReturn
            // 1. 返回 != null,我們認(rèn)為 operator 已經(jīng)對實際訂閱者做了包裝繁调。所以繼續(xù)調(diào)用下一個操作符(也就是當(dāng)前操作符的上游)
            // 2. 如果返回 == null萨蚕,則代表 operator 要自己處理上游的消費和下游的訂閱,方法結(jié)束
            subscriber = operator.subscribeOrReturn(subscriber);
            if (subscriber == null) {
                // null means "I will subscribe myself", returning...
                return;
            }
            // 返回當(dāng)前 operator 的下一個操作符(也就是返回的上游的操作符)
            OptimizableOperator newSource = operator.nextOptimizableSource();
            if (newSource == null) {
                // 如果所有 operator 都執(zhí)行完了蹄胰,那么可以直接向 Publisher 發(fā)起訂閱了
                // 訂閱結(jié)束后岳遥,退出當(dāng)前方法
                operator.source().subscribe(subscriber);
                return;
            }
            // 存在下一個操作符,繼續(xù)執(zhí)行該邏輯
            operator = newSource;
        }
    }
    catch (Throwable e) {
        Operators.reportThrowInSubscribe(subscriber, e);
        return;
    }
}

在理解了 subscribe 的邏輯之后裕寨,我們在以后在閱讀 Reactor 操作符的源碼時寒随,就可以清楚地知道只需要關(guān)注該操作符的 subscribeOrReturn 方法即可。

如果 subscribeOrReturn 僅是返回一個 subscriber帮坚,那么我們只需要關(guān)注其 Subscriber 的相關(guān)邏輯即可妻往。如果返回的 null,則代表該操作符要自行消費上游然后向下游傳遞訂閱试和,我們需要關(guān)注他的 Subscription 相關(guān)

最后

如果覺得我的文章對你有幫助讯泣,動動小手點下關(guān)注,你的支持是對我最大的幫助

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阅悍,一起剝皮案震驚了整個濱河市好渠,隨后出現(xiàn)的幾起案子昨稼,更是在濱河造成了極大的恐慌,老刑警劉巖拳锚,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件假栓,死亡現(xiàn)場離奇詭異,居然都是意外死亡霍掺,警方通過查閱死者的電腦和手機(jī)匾荆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杆烁,“玉大人牙丽,你說我怎么就攤上這事⊥没辏” “怎么了烤芦?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長析校。 經(jīng)常有香客問我构罗,道長,這世上最難降的妖魔是什么智玻? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任绰播,我火速辦了婚禮,結(jié)果婚禮上尚困,老公的妹妹穿的比我還像新娘蠢箩。我一直安慰自己,他們只是感情好事甜,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布谬泌。 她就那樣靜靜地躺著,像睡著了一般逻谦。 火紅的嫁衣襯著肌膚如雪掌实。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天邦马,我揣著相機(jī)與錄音贱鼻,去河邊找鬼。 笑死滋将,一個胖子當(dāng)著我的面吹牛邻悬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播随闽,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼父丰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掘宪?” 一聲冷哼從身側(cè)響起蛾扇,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤攘烛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后镀首,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坟漱,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年更哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了芋齿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡竖瘾,死狀恐怖沟突,靈堂內(nèi)的尸體忽然破棺而出花颗,到底是詐尸還是另有隱情捕传,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布扩劝,位于F島的核電站庸论,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏棒呛。R本人自食惡果不足惜聂示,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望簇秒。 院中可真熱鬧鱼喉,春花似錦、人聲如沸趋观。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皱坛。三九已至编曼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剩辟,已是汗流浹背掐场。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留贩猎,地道東北人熊户。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像吭服,于是被迫代替她去往敵國和親敏弃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

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