1. 程式人生 > >Reactive Spring實戰 -- 理解Reactor的設計與實現

Reactive Spring實戰 -- 理解Reactor的設計與實現

Reactor是Spring提供的非阻塞式響應式程式設計框架,實現了Reactive Streams規範。 它提供了可組合的非同步序列API,例如Flux(用於[N]個元素)和Mono(用於[0 | 1]個元素)。 Reactor Netty專案還支援非阻塞式網路通訊,非常適用於微服務架構,為HTTP(包括Websockets),TCP和UDP提供了響應式程式設計基礎。 本文通過例子展示和原始碼閱讀,分析Reactor中核心設計與實現機制。 文字Reactor原始碼基於Reactor 3.3 #### 名詞解析 響應式程式設計,維基百科解析為 >reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change. This means that it becomes possible to express static (e.g. arrays) or dynamic (e.g. event emitters) data streams with ease via the employed programming language(s) 響應式程式設計是一個專注於資料流和變化傳遞的非同步程式設計正規化。 這意味著使用程式語言可以很容易地表示靜態(例如陣列)或動態(例如事件發射器)資料流。 下面簡單解釋一下相關名詞。 **資料流與變化傳遞**,我的理解,資料流就如同一條車間流水線,資料在上面傳遞,經過不同的操作檯(我們定義的操作方法),可以被觀測,被過濾,被調整,或者與另外一條資料流合併為一條新的流,而操作檯對資料做的改變會一直向下傳遞給其他操作檯。 java 8 lambda表示式就是一種資料流形式 ```java lists.stream().filter(i -> i%2==0).sorted().forEach(handler); ``` lists.stream(),構建一個數據流,負責生產資料。 filter,sorted方法以及handler匿名類,都可以視為操作檯,他們負責處 理資料。 這裡還涉及兩個概念 **宣告式程式設計**,通過表示式直接告訴計算機我們要的結果,具體操作由底層實現,我們並不關心,如sql,html,spring spel。 對應的**指令式程式設計**,一步一步告訴計算機先做什麼再做什麼。我們平時編寫java,c等程式碼就是指令式程式設計。 上例中通過filter,sorted等方法直接告訴計算機(Spring)執行過濾,排序操作,可以理解為宣告式程式設計。 注意,我的理解是,宣告式,指令式程式設計並沒有明確的界限。 越是可以直接通過宣告表達我們要什麼,就越接近宣告式程式設計,反之,越是需要我們編寫操作過程的,就越接近指令式程式設計。 如Spring中的宣告式事務和程式設計式事務。 可參考:https://www.zhihu.com/question/22285830 **函數語言程式設計**,就是將函式當做一個數據型別,函式作為引數,返回值,屬性。 Java不支援該模式,通過匿名類實現,如上例中forEach方法。 注意,函數語言程式設計還有很多學術性,專業性的概念,感興趣的同學可以自行了解。 響應式程式設計,主要是在上面概念加了非同步支援。 這個非同步支援非常有用,它可以跟Netty這些基於事件模型的非同步網路框架很好地結合,下一篇文章我們通過WebFlux來說明這一點。 #### 資料流轉 下面我們來簡單看一下Reactor的設計與實現吧。 首先通過一個小用例,來看一個Reactor中如何生產資料,又如何傳遞給訂閱者。 ```java @Test public void range() { // [1] Flux flux = Flux.range(1, 10); // [2] Subscriber subscriber = new BaseSu