Spring框架推出5.0,其中包含了Web Flux,與過去咱們所知的Spring Web MVC的差別是什麼?開發者們準備好接受另外一套模型了嗎?新版Spring的一大特點,就是Reactive Web方案的Web Flux,這是用來替代Spring Web MVC的嗎?或者,只是終於能夠再也不基於Servlet容器了?編程
基於Servlet容器的Web MVC安全
身爲Java開發者,對於Spring框架並不陌生。它最初起源於2002年,是Rod Johnson的著做「Expert One-on-One J2EE設計與開發」中的界面框架。到了2004年,推出Spring 1.0,從XML到3.0以後,開始支援JavaConfig設定; 進一步地,在2014年時,除了Spring 4.0以外,首次發表了Spring Boot,最大的亮點是採用自動組態,令基於Spring的快速開發成爲可能。網絡
對Web開發者來講,Spring中的Web MVC框架,也一直隨着Spring而成長,然而因爲基於Servlet容器,早期被批評測試不易(例如:控制器中包含了Servlet API)。框架
不過,從實做Controller介面搭配XML設定,到後來的標註搭配JavaConfig,Web MVC使用愈來愈便利。若是願意,也可採用漸進的方式,將基於Servlet API的Web應用程序,逐步重構爲幾乎沒有Servlet API的存在(可參考先前專欄文章<篩選框架必要功能>),在程式碼層面達到屏壁Servlet API的效果。函數
因爲很多Java開發者的Web開發經驗,都是從Servlet容器中累積起來的,在這個時候,Web MVC框架基於Servlet API,就會是一項優勢。由於,雖然運用Web MVC撰寫程式時,可作到不直接面對Servlet API,然而,也意味着更強烈地受到Spring的約束,有時則是沒法在龐雜設定或API中找到對應方案,有時也由於心智模型仍是掛在Servlet容器,經驗上難以脫離,在搞不出的HttpSession,ServletContext的對應功能時,直接從HttpSession中,ServletContext的下手,畢竟也是個方法。測試
撰寫程式時,就算沒用到Servlet API,Web MVC基於Servlet容器還是事實,由於,底層仍是得藉助Servlet容器的功能,例如Spring Security,本質上仍是基於Servlet容器的過濾器方案。設計
然而在今日,Servlet被許多開發者視爲陳舊,過期技術的象徵,或許是由於這樣,在Java EE 8宣佈推出的這段期間,當我在某些場合談及Servlet 4.0之時,總會聽到有人提出「Web Flux能夠脫離Servlet了」之類的善心建議。對象
實現Reactive Streams的Reactorblog
Web Flux不依賴Servlet容器是事實,然而,在談及Web Flux以前,咱們必須先知道Reactor專案,它是由Pivotal公司,也就是目前Spring的擁有者推出,實現了Reactive Streams規範,用來支援Reactive編程的實做品。ip
既然是實現了Reactive Streams規範,開發者必然會想到的是RxJava / RxJava 2,或者至是Java 9的Flow API。這也意道着,在能使用Web Flux以前,開發者必須對於Reactive Programming典範,有所認識,若是你從未接觸過這些玩意兒,能夠參考先前專欄<Reactive與Java 9>。
開發者這時有疑問了,Spring爲什麼不直接基於RxJava 2,而是打造專屬的Reactive Streams實做呢?
就技術而言,Reactor是在Java 8的基礎上開發,並全面擁抱Java 8以後的新API,像是Lambda相關介面,新日期與時間API等,這意謂着,專案若是仍是基於Java 7或更早版本,就沒法使用電抗器。
在API層面,RxJava 2有着由於歷史發展脈絡的緣由,不得不保留一些使人容易困惑或混淆的模態或操做,而Reactor在這方面,都有着明確的對應API來取代,然而,卻也提供與RxJava 2(甚至是Flow API)間的轉換。
另外一方面,Reactor較直覺易用,例如最常介紹的Mono與Flux,實現了Reactive Streams的發佈者介紹,並簡化了訊息發佈,讓開發者在許多場合,不用處理Subscriber和Subscription的細節(固然,這些在Reactor也予以實現)。而在Spring Web Flux中,Mono與Flux也是主要的操做對象。想知道如何使用Mono與Flux,能夠參考<使用Reactor進行反應式編程>(https://goo.gl / vc2fGc)。
又一個的Web框架?
到了春天5,在Reactor的基礎上,新增了Web Flux做爲Reactive Web方案,咱們在許多介紹文件的簡單範例,例如<使用Spring 5的WebFlux開發反應式Web應用>(https://goo.gl / G5uotZ),就看到當中使用了Flux,Mono來示範,並且,程式碼看起來就像是Spring MVC。
這是由於Web Flux提供了基於Java標註的方式,有許多Web MVC中使用的標註,也拿來用於Web Flux之中,讓熟悉Web MVC的開發者也容易理解與上手Web Flux,然而,這不過就是新的網絡框架嗎?
實際上,固然不是如此.Web Flux並不是依賴Web MVC,並且它是基於Reactor,本質屬於非同步,非阻斷,Reactive Programming的心智模型,也所以,若是打算將Web Flux運行在Servlet容器之上,必須是支援Servlet 3.1以上,由於纔有非阻斷輸入輸出的支援,雖然Web Flux的API在某些地方,確實提供了阻斷的選項,若單純只是試着將基於Web MVC的應用程式,改寫爲套用Web Flux,並不會有任何益處,反而會窮於應付如何在Web Flux實現對應的方案。
例如,Spring Security顯然就不能用了,畢竟是Spring基於Servlet的安全方案,開發者必須想辦法套用Spring Security Reactive;並且,在儲存方案上,也不是直接採用Spring Data,而不是Spring Data反應等。
就算能套用相關的設定與API,要能得到Web Flux的益處,應用程式中相關的元件,也必須全面檢視,從新設計爲非阻斷,基於Reactive Programming方式,這或許纔是最困難,麻煩的部份。
除了基於Java標註的方式,讓熟悉Web MVC的開發者容易理解以外,Web Flux還提供了基於函數式的設計與組態方式。
實際上,在運用RxJava 2 / Reactor等Reactive Streams的實做時,咱們也都必須熟悉函數式的思考方式,才能充分掌握,這點在Web Flux並不例外。
能夠脫離的Servlet容器了?
Servlet容器是個舊時代的象徵,若是可以屏蔽Servlet容器或相關API,許多開發者應應都會很開心,能夠少一層抽象,沒必要使用肥肥的Servlet容器,固然會是使用Web Flux時附帶的優勢,然而,若是隻是爲了屏蔽的Servlet,其實,早就有其餘技術選擇存在。
基於Servlet一路發展過來的Web MVC,雖然目前在某些地方能夠安插一些函數式的設計,然而,本質上不變的部分在於,在技術堆疊中所隱含的,還是一個基於同步,阻斷式,命令式的心智模型。若是在這樣的堆疊中,開發者總是由於想要實現非同步,非阻斷,Reactive,函數式而感到不快,Web Flux也許纔會是可考慮的方案,而不單只是用來做爲脫離Servlet容器,Web MVC的替代品。
總體而言,Web Flux還算是新技術,也還有待時間驗證可行性,若是隻是爲了想用Web Flux來取代Web MVC,或甚至更小一點的野心,只是想要能脫離Servlet容器,最好在採起行動以前,全面檢視一下,確認自身或團隊成員是否準備好接受Web Flux的心智模型,或者真的存在着對應的應用場景吧!