RxJava 源碼筆記(1)

  1. Notification: An object representing a notification sent to an {@link Observable}

    • 註釋已經解釋的很清楚,代表的是響應式編程信息流中的一條消息(onNext/onError/onComplete)
    • 正如上面所說的,Notification承載的是複數種類型,因此需要一個Kind對象來進行標記屬於哪種信息。
      • Kind是一個枚舉類: 有三個枚舉值: OnNext, OnError, OnCompleted 和Observer的回調一一對應,這也是必然的。
    • 同樣,因爲onNext會攜帶某個對象,而onError則會攜帶某個Throwable, 因此Notification中也需要維護這樣兩個引用。
    • onCompleted因爲本身不攜帶任何信息,因此一個單例不變對象就足夠了:

      • private static final Notification ON_COMPLETED = new Notification(Kind.OnCompleted, null, null);
    • Notification的構造算是工廠模式,其構造被封裝在類本身的static的createOnXXXX函數中.

    • 如果你想把某個Notification**投遞給一個Observer,可以調用accept**(Observer<? super T> observer)
    • 綜述其實Notification是一個很簡單的消息類型集成類,封裝了一些輔助方法。
  2. NotificationLite: 其表徵的含義和Notification一樣,不過更多的作爲內部使用(比如在materialize/dematerialize 這樣的operator的實現中).
    • 關鍵的一點: NotificationLite類本身扮演的不是一條lite的Notification(簡化的信息即LiteNotification),扮演這個角色的是其內部的2個單例對象和一個內部類, NotificationLite本身像是liteNotification的一個Utils
    • liteNotification和Notificaton的區別: Notificatiion包含了完整信息,對數據進行了封裝,本身就是一個完整的信息個體, 而LiteNotification不對數據進行封裝,沒有包含Kind等輔助信息,其使用必須依託於NotificationLite這個Utils提供的輔助函數**。
    • 採用了單例模式,NotifictionLite本身只有一個實例,因爲如同開始說的,NotificationLite本質是一個Utils
    • 真正的liteNotification通過下面幾類對象來區分的:
      • ON_COMPLETED_SENTINEL 單例的 Serializable對象,代表 onCompleted
      • ON_NEXT_NULL_SENTINEL 單例的 Serializable對象, 其代表的是onNext(null),對於非null的情況,onNext傳輸的對象本身就代表了onNext
      • class OnErrorSentinel implements Serializable, 代表 onError, 因爲需要封裝Throwable, 因此不能單例。
    • NotificationLite的accept函數接受一個Observer和一個Object:
      • 和Notification的accept不同,因爲Notification自身已經代表了一條消息,那麼顯然只需要一個Observer就足夠,而NotificationLite從其定位上講,顯然這時候扮演的Utils是需要一個LiteNotification(這裏是一個Object對象)的。
      • 如果LiteNotification 是 ON_COMPLETED_SENTINEL,只需要調用Observer的onCompleted即可
      • 如果LiteNotification 是 ON_NEXT_NULL_SENTINEL,調用onNext(null)
      • 如果傳入的Object是OnErrorSentinel類型,提取出Error並調用onError(Error)
      • 否則該對象對應的就是一個非空的onNext, 直接類型轉化並調用onNext, onNext((T) object)
      • 不接受object等於null,因爲這是無意義的行爲(你投遞了一條沒有信息的信息).
    • NotificationLite的next(T t)函數和Notification的createOnNext代表的意義一樣,都是得到一個onNext Notification. 但是因爲LiteNotification的特性,next()函數的邏輯很簡單,如果t是null,那麼返回單例ON_NEXT_NULL_SENTINEL,否則直接返回t(因爲accpect函數的邏輯要求這樣)
    • completed()/error(Throwable e)同樣,不贅述。
    • 也實現了isNext/isError等方法,同樣基於LiteNotification的特性。
    • kind方法基於LiteNotification返回其代表的實際的Notification的Kind.
    • 綜合看,NotifiationLite在使用時避免了拆包和封包(這裏的包指的是Notification)的開銷, 在內部使用時,完全可以取代Notification的角色(因爲內部使用一般確實用不到Notification的完整信息,只關注行爲本身)。
  3. SubjectSubscriptionManager<T> extends AtomicReference<SubjectSubscriptionManager.State<T>> implements OnSubscribe<T>
    • 實現了狀態機功能(主要是Subject的某些特性需要) 和 OnSubcribe(Subject作爲Observable的需要)。
    • Object latest: 保存了上一個發出的信息的值或者結束時的值。
    • Action1<SubjectObserver<T>> onStart/onAdded/onTerminated, 三個回調操作,其接受的參數是一個Observer,一般來說就是一個Subscriber:
      • onStart: 有一個新的Subscriber要進行subscribe,在其被加到state前會被調用。
      • onAdded: 在Subscriber被加入到state之後會被調用。
      • onTerminated: 當Subscriber想要subscribe一個terminal state會被調用。
    • nl = NotificationLite.instance(): 前面介紹過,內部使用的LiteNotification的Utils。
    • State本身的功能很簡單,內部維護了:
      • boolean terminated 代表着信息流是否結束。
      • SubjectObserver[] observers, 一個subscribe了Subject的observer的集合列表。
      • add/remove函數可以增加/刪除observer,不過要注意的是,add/remove本身並不改變對象本身(如果確實改變了observers), 而是返回一個應用了改變的新的state對象(爲什麼會這麼做,下面在解釋SubjectSubscriptionManager的add/remove時會解釋)
      • 同樣內部已經預置幾個對應特殊場景的State對象(享元模式):
        • TERMINATED = new State(true, NO_OBSERVERS) 代表一個已經Terminate的Subject, 沒有observer
        • EMPTY = new State(false, NO_OBSERVERS) 代表一個還沒有Terminate的Subject, 沒有observer
    • SubjectSubscriptionManager 本身繼承自AtomicReference 因此其本身就可以看待爲一個State。
    • 作爲一個OnSubscribe,實現了call(final Subscriber<? super T> child)函數,在Subscriber subscribe時會被調用:
      • 首先將Subscriber(child)進一步裝飾爲一個SubjectObserver(bo)
      • 然後調用addUnsubscriber(child, bo)爲Subscriber**添加一個Subscriber進行unSubscribe時的回調**, 該回調的操作是將bo從State的Observers中移除。
      • 回調onStart(bo)
      • 如果child沒有被UnSubcribe, 那麼調用add(bo)將bo加入到State的Observers中。
    • 爲了對外提供訪問/修改observers的方式, 有以下函數:
      • add(SubjectObserver<T> o):
        • 首先獲取當前的state, 視爲oldState
        • 如果發現oldState已經Terminate, 那麼沒有必要再將Observer進行add,直接回調onTerminated.
        • 否則調用state的add,注意State的特性,這裏state對象本身不會改變,而是會返回一個修改過的新的State對象
        • 調用AtomicReference的CAS方法實現原子不加鎖來更新爲最新的State對象,並回調onAdd.
        • 上面的流程被包在一個do while(true)死循環中,能跳出的兩個契機是state本身Terminate或者CAS新的State對象成功。
        • add/remove的實現解釋了State的add/remove的特殊性,這裏爲了兼顧性能和多線程,採用的CAS這種不加鎖的方式來實現了多線程安全,同樣保證了性能
      • remove(SubjectObserver<T> o):
        • 基本同上。
      • observers(): 返回observers數組。
    • SubjectObserver<T> implements Observer<:
      • 應用了裝飾模式, 對構造時傳入的Subscriber進行了裝飾,不過onNext/onComplete/onError則是直接轉發給被裝飾的Subscriber。
      • 裝飾的新功能體現在對NotificatinLite的支持上.:
        • emitNext(Object n, final NotificationLite<T> nl):
          • 將n(一個LiteNotification, 因此需要NotificationLite)作爲一個消息發出去。
          • 內部調用synchronized (this)會和下面兩個函數競爭,從而阻塞其他函數。
          • 如果現在正在emit(發送信息),會將該消息加入到queue中.
        • emitFirst(Object n, final NotificationLite<T> nl);
          • 首先會判斷是否真的是第一次emit(內部一個flag來保證),如果不是第一次,直接返回。
          • 如果正在emiting,那麼也返回。
          • 調用emitLoop(null, n, nl)將n發送出去。
        • emitLoop(List<Object> localQueue, Object current, final NotificationLite<T> nl)
          • 先把localQueue中所有的信息發出去。
          • 然後再發送current。
    • next(Object n):
      • 設置一個LiteNotification爲Latest,並且返回當前active的observers
    • terminate(Object n):
      • 設置一個LiteNotification爲Latest
      • 設置active爲false代表terminate
      • 獲取當前的set,如果set已經terminate,那麼返回State.NO_OBSERVERS代表沒有一個observer
      • 否則設置當前的set爲State.TERMINATED,並返回其observers。
    • 綜合來看,SubjectSubscriptionManager實現了對多個observer的通知和管理,並且是多線程安全的,其作爲OnSubscribe實現的功能主要是將subcriber加入到自己的observers中,並通過設置Subscriber,使其在unsubcribe時能被從observers中remove,同時還有onStart等回調來提供一套整體observers變化時的回調機制,這也貼切了其命名: 一個Subject的衆多Subscription的manager
  4. BehaviorSubject:

    • 該Subject有這樣一個特性: 當有Subscriber要subscribe它時,如果該Subject之前已經發出了信息或者結束,那麼該Subscriber會收到最近一次發送的信息(包括結束), 例子:

      // observer will receive the “one”, “two” and “three” events, but not “zero”
      BehaviorSubject subject = BehaviorSubject.create(“default”);
      subject.onNext(“zero”);
      subject.onNext(“one”);
      subject.subscribe(observer);
      subject.onNext(“two”);
      subject.onNext(“three”);

      // observer will receive only onCompleted
      BehaviorSubject subject = BehaviorSubject.create(“default”);
      subject.onNext(“zero”);
      subject.onNext(“one”);
      subject.onCompleted();
      subject.subscribe(observer);

    • 從上面的例子可以看出BehaviorSubject的特性,同時還可以看到,BehaviorSubject是的,和通常的Observable不一樣,BehaviorSubject不是在被Subscriber subscribe時纔開始自己的信息流,完全可以通過調用其onXXXX方法在沒有Subscriber的情況下開始自己的信息流
    • BehaviorSubject可以有多個Observer, 管理Observer以及向Observer投遞信息的職責全部委託給了SubjectSubscriptionManager
    • BehaviorSubject在構造的時候就會創建一個SubjectSubscriptionManager, 同時BehaviorSubject的構造函數還接受一個defaultValue, 該defaultValue在Subject的信息流還沒有真正開始時,如果Observer來Subscribe,會被作爲信息傳遞給Observer
    • SubjectSubscriptionManager的onAdded和onTerminated被根據BehaviorSubject的特性來配置:
      • 傳輸Latest的信息給Observer. 通過調用SubjectObserver的emitFirst.
      • 這樣就實現了BehaviorSubject的特性,在Observer subscribe時,會收到BehaviorSubject的最近一條信息。
    • 因爲BehaviorSubject同時又是一個Observer,因此其也需要實現onNext/Error/Completeted等函數:
      • 因爲Subject本身是一箇中繼,因此其onXXX方法本質都是遍歷SubjectSubscriptionManager的observers並調用其emitNext來將信息傳遞給observers. 爲了歸一化onXXXX使得可以統一調用emitNext來處理,這裏使用了NotificationLite來進行歸一化
      • 作爲一個的Observable, BehaviorSubject開始發送信息不再依賴於Subscriber的subscribe來觸發,完全可以直接調用其onXXX方法來開始Subject的信息流,不必在意是否有Subscriber,信息流開始和發送完全自主。
      • 對於onError/Completed來說,除了調用emitNext將Notification散佈給observers外,還需要調用SubjectSubscriptionManager的terminate(Object n(代表一條liteNotification))函數將SubjectSubscriptionManager的狀態設置爲active=false代表着信息流的終結, 並且釋放observers.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章