IT 技術發展太快了,就像浪潮同樣一波接着一波,朝你迎面撲來,稍不留神就會被巨浪卷至海底而不得翻身。咱們必需要學會抓住那些不變的本質或規律,只有這樣才能屹立潮頭而不倒,乘風破浪,作這個鉅變時代的弄潮兒!前端
2003年,Rod Johnson 建立了 Spring,我在那一年開始了研究生實習。2005年參加工做,通訊行業,主力開發語言是 C/C++。在校勤工儉學時搗鼓過 JSP,2005年先後我開始自學 Spring 搭建我的網站,那時 Java 領域最火的開發框架組合就是:Struts + Spring + Hibernate,SSH。2009年,我跳槽到了移動互聯網行業,主力開發語言逐漸轉爲 Java。2014年,我再次跳槽進了互聯網金融行業,基於 Spring 擴展定製內部開發框架,從 Spring 用戶變成了擴展開發者。2016年因參與內部雲平臺建設,我跟 Spring 的東家 Pivotal 公司還有過一次合做。隨着微服務等技術的興起,近些年我作了許多 Spring Boot\Spring Cloud 擴展定製和培訓推廣。web
一晃眼十五年過去了,從取代 EJB 的輕量級開發框架開始,到無比強大的生態圈,再到 Spring Boot\Spring Cloud 從新塑身成爲雲原生應用開發領域的首選框架。Spring 早已不是最初的模樣了,在它身上發生過無數變化,但惟一不變的是它仍舊穩坐 Java 開發框架領域的頭把交椅。或許大部分讀者都熟悉 Spring 的使用,但你知道它背後的核心技術有哪些嗎?這些年它都發生過哪些重大的變化?它演進至 Spring Boot/Spring Cloud 的緣由是什麼?它的成功源於哪些關鍵的產品設計理念?...... 熟悉 Spring 的使用僅僅是"知其然",惟有"知其因此然",咱們才能真正融會貫通用好它。快來吧,千萬不要錯過!老兵用血汗經驗爲你剖析那些風雲變幻中的不變量:spring
Spring 背後的核心技術數據庫
Spring 演進發展的歷程編程
Spring Cloud 蝶變重生安全
Spring 的產品設計理念架構
Spring 的產品推廣策略mvc
...... app
適讀人羣:開發、測試、架構、產品等框架
1. Spring 背後的核心技術
Java EE 或 J2EE,都是 Java Platform Enterprise Edition 的簡稱,它是一套開發分佈式企業級應用的規範和標準,由一整套服務(Services)、應用程序接口(APIs)和協議構成,下面是 J2EE 涵蓋的13種技術規範:
JDBC:Java Database Connectivity
JNDI:Java Naming and Directory Interface
EJB:Enterprise Java Bean
RMI:Remote Method Invocation
Java IDL for CORBA
JSP:Java Server Pages
Java Servlet
XML:Extensible Markup Language
JMS:Java Message Service
JTA:Java Transaction API
JTS:Java Transaction Service
Java Mail
JAF:JavaBeans Activation Framework
生產力決定生產關係,而科學技術是第一輩子產力。Java 最先是由 Sun Microsystems 公司發明的高級編程語言,EJB 也是由 Sun Microsystems 公司推行的 J2EE 標準規範,而 Spring 卻取代 EJB 成了事實標準,以世俗的眼光看,這是一個經典的以弱勝強的故事。當時,EJB 的背後有許多知名的商業公司提供強力支持,而 Spring 僅僅是 Rod Johnson 我的的玩票做品,爲何最終結局出乎意料呢?其實,弱是沒法勝強的,只是當時世人看不懂 Spring 比 EJB 強在什麼地方,如今咱們再去剖析就知道它強在技術上,先進的技術造就了 Spring 的輕量和易用,再加上開源免費的商業模式,最終贏得用戶。
那究竟哪些核心技術造就了 Spring 的輝煌呢?除了最著名的控制反轉 IOC、依賴注入 DI 和麪向切面編程 AOP 等外,還有 MVC、Taglib、ORM、Annotation 等,以及對 J2EE 其餘標準規範的支持,包括:JDBC、JNDI、RMI、JMS 等,接下來咱們簡單介紹一下這些關鍵技術,若是想更加深刻的瞭解,你們能夠找資料作專題學習。
1.1 IOC / DI / AOP
Spring 做爲開源框架,爲了下降企業應用的開發複雜度的人建立,但如今它已經不限於企業應用這個領域了,而是一個輕量級的控制反轉 IoC(Inversion of Control)和麪向切面 AOP(Aspect Oriented Programming)的容器框架。經過 IoC 技術讓應用達到鬆耦合的目的,經過面向切面編程分離業務邏輯與系統服務。IoC 容器負責管理全部應用對象的配置和生命週期,將簡單的組件配置、組合成爲複雜的應用。
控制反轉 IoC 的另一個說法就是依賴注入 DI(Dependency Injection),它規範了對象與被依賴對象之間的裝配過程,對象經過構造器參數、工廠方法參數、屬性設置函數來聲明依賴關係。IoC 容器提供裝配和管理 Bean 功能,整個裝配過程由 IoC 容器調度控制的,它在建立對象實例過程當中將其所依賴的實例注入,這跟 Bean 直接經過構造器或者 Service Locator 模式本身控制初始化或定位所依賴實例的過程是相反的。
接口 org.springframework.context.ApplicationContext 就表明了 Spring IoC 容器,它負責初始化、配置、裝配和管理所有 Bean。IoC 容器經過讀取 XML、註解或 Java 類中配置元數據得到初始化、配置和裝配相關的指令,咱們採用上述配置方式來描述構成應用的對象及彼此之間的依賴關係。IoC/DI 讓應用再也不強依賴框架,藉助配置文件、註解等方式就能夠靈活裝配出應用程序,前端 Web 框架已經興替了無數款:Struts、Webwork、JSF、Tapestry、AngularJS、React、Vue 等等,持久層也有很多選擇:Hibernate、iBatis、MyBatis 等,但裝配領域惟有 Spring 一枝獨秀。
從裝配這個角度看,Spring 對業務是非侵入性的,業務代碼不依賴 Spring,即剝離 Spring 從新換一套框架或者本身寫一套組裝代碼,原先的業務代碼是能夠重用的。IoC 最初的目的就是充分利用 OO 的多態性,經過配置文件而不是硬編碼來實例和裝配對象,這樣就爲具有了爲不一樣客戶場景提供服務的靈活性。
AOP 經過靜態期預編譯或運行期動態代理等方式實現不修改源代碼的狀況下給程序動態統一添加功能,它給出了獨特的編程視角,以切面方式控制系統的各個處理環節,爲許多業務場景提供優雅的解決方案,例如:將日誌記錄、性能統計、安全控制、事務處理、異常處理等代碼從業務邏輯代碼中劃分出來,修改這些行爲時不影響業務代碼。
1.2 MVC / MVP / MMVM
視圖(View):用戶交互界面,數據展現。
控制器(Controller):處理請求的業務邏輯,選擇視圖展現。
模型(Model):業務邏輯和數據,數據保存訪問操做。
View 接受用戶操做指令,並傳送指令至 Controller。
Controller 完成業務邏輯處理以後,要求 Model 改變狀態。
Model 將新數據發送到 View,用戶獲得更新反饋。
MVP 模式將 MVC 中的 Controller 改成 Presenter,同時改變了通訊方向。
每一個部件之間的通訊都是雙向的。
View 跟 Model 不直接交互,所有經過 Presenter 傳遞。
View 很是薄,不包含任何業務邏輯,稱做"被動視圖"(Passive View),即沒有任何主動性,而 Presenter 很是厚,全部邏輯都部署在那裏。
MVVM 模式將 Presenter 更名爲 ViewModel,基本上與 MVP 模式徹底一致。惟一的區別是,它採用雙向綁定(data-binding):View 的變更,自動反映在 ViewModel,反之亦然。React 和 Vue 等都採用這種模式。
1.3 JDBC / ORM
Java 數據庫鏈接 JDBC(Java DataBase Connectivity)是用於執行 SQL 語句的 Java API,能夠爲多種關係數據庫提供統一訪問:
對象關係映射 ORM(Object Relational Mapping),是一種用於實現面向對象編程語言裏對象跟不一樣類型關係數據庫數據之間的轉換技術:
2. Spring 演進發展的歷程
2002年,老兵哥我本科畢業,當時正是 J2EE、EJB 最火的時候,許多業內知名的大公司(例如:Sun Microsystems、Oracle、IBM 等)都在推進 EJB 相關技術的發展和落地。當年仍是年輕小夥的美國人 Rod Johnson 認爲 EJB 太過於臃腫,並非全部項目都適用 EJB 這種重型框架,他堅信有其餘更加優雅的解決方案。爲了驗證本身的想法,Rod Johnson 在2002年10月出版了一本書《Expert one on one J2EE development without EJB》,在書中他剖析了 J2EE、EJB 框架中存在的一些關鍵缺陷。Rod Johnson 堅決地認爲:
J2EE 應該變得更易於使用。
面向接口(Interface)編程要優於面向類(Class),面向接口能夠極大地下降複雜度。
JavaBean 提供了一種很是好的應用配置途徑。
面向對象設計比任何一種實現技術都更加劇要,包括 J2EE。
檢查型異常在 Java 當中被過分使用,當系統不能從異常中恢復時,平臺不該該強迫你去捕獲異常。
可測試性是很是重要的,像 Spring 這樣的平臺應該幫助你把代碼變得更易於測試。
使用 Spring 應該是件愉悅的事情。
用戶的應用代碼不該該依賴任何 Spring 的 APIs。
Spring 不該該跟如今已有的優秀解決方案競爭,而是要開放地集成這些第三方組件。
同時,他提出了一套基於普通 Java 類依賴注入的輕量級解決方案,而且以一個在線座位預約系統爲例演示瞭如何在不使用 EJB 的狀況下構建高質量、可擴展的系統。爲了構建這個演示應用,他編寫了超過 30,000 行的基礎結構代碼,隨書籍開源而別普遍引用。因爲該開源工程的根包命名爲:com.interface21,因此你們最初稱這套開源框架爲:Interface21,它就是 Spring 的前身,這是一個無意插柳柳成蔭的故事。
隨着 Interface21 被愈來愈多的用戶承認及使用,Rod Johnson 擁有了跟 EJB 平起平坐的勇氣和信心,後來他就開始全職投入,並在2004年3月24日對外發布了 Spring Framework 1.0 final。當時,整個 Spring 就是一個完整的項目,全部功能都包含在這個項目當中,其中包含最核心的控制反轉 IOC 和麪向切面編程 AOP,除此以外還包括:JDBC、Mail、ORM、事務、定時任務、Spring MVC等配套功能。
站在今天回望過去,當年 Rod Johnson 還作對了一件事情,就是擁抱開放、開源,在 Spring 1.x 階段就已經支持許多第三方開源框架了,例如:Struts、Hibernate、iBatis、模板引擎等。從 Spring 誕生到如今的十五年左右時間,正是軟件開源運動蓬勃發展的十五年。Spring 藉助開源社區的力量,匯聚全球貢獻者,才造成了無比強大的生態圈,才具有了與傳統軟件業巨頭競爭的能力,而 EJB 選擇了封閉,差之毫釐謬以千里。
2.1 Spring 1.x
Spring 1.x 主要知足了當時正在興起的企業應用規模化開發需求,當時 J2EE 應用的經典架構是分層架構:表現層、業務層、持久層,最流行的組合就是 SSH:Struts、Spring、Hibernate。Spring 1.x 僅僅支持基於 XML 的配置,確保用戶代碼不依賴 Spring。Spring 1.x 主要包含了如下功能模塊:aop、beans、context、core、dao、ejb、jdbc、jndi、mail、metadata、orm、remoting、scheduling、transation、ui、util、validation、web 等。
2.2 Spring 2.x
相對於 Spring 1.x,2.x 並無發生太大的改動,主要是在 1.x 的基礎上漸進式的加強,增長了下述新的功能模塊:cache.ehcache、instrument、jca、jms、jmx、scripting、stereotype 等。
老兵哥以爲,用戶就像手中的沙子,抓的越緊漏的越快,Spring 倡導不綁定用戶,業務代碼不依賴 Spring,隨時能夠從 Spring 遷移到其餘框架下,Spring 對鬆耦合的堅持反而讓愈來愈多的用戶從 EJB 轉投至它的名下。在勢頭正猛之時,Spring 2.x 順勢推出了對 Java Annotation 的支持。雖然基於註解的配置對用戶代碼存在必定的***,但該特性能夠極大地方便用戶,配置跟代碼在一塊兒,這樣更加直觀便於維護。
2.3 Spring 3.x
Spring 以簡單適配的方式集成第三方開源組件,隨着它自己的功能愈來愈豐富,以及生態圈愈來愈強大,單個項目工程已經沒法知足開發、維護和使用的要求了,Spring 3.x 將原先單個工程項目拆解成多個子項目,這樣方便用戶按需選用,不像先前的版本,無論用與不用都要引入所有模塊。化整爲零,這個變化帶來了很是大的影響,Spring 不只是功能模塊的堆積了,它開始標準化集成相關的技術了,這有利於構建更加龐大的生態,也更利於得到新的用戶。
爲何這麼說呢?原先 Spring 是一個總體,用戶選不選它是比較大的技術決策,而如今每一個組件都是能夠單獨引入的,相對原先的決策範圍變小了,風險也就下降了,用戶能夠先小範圍試用,下降了用戶上車的難度。等用戶使用上 Spring 的組件,那麼跟用戶就創建了鏈接,讓用戶有更多機會了解 Spring,從而影響用戶選用更多的組件。
Spring 框架被拆解成多個組件,它能夠爲不一樣應用架構提供基礎的支持,包括消息、事務管理、持久化和前端組件等,它不只包括 Servlet-based 的 Spring MVC 前端 Web 框架,還包括 Spring WebFlux 等響應式 Web 框架,用戶能夠按需選擇。
在支持 XML、Annotation 配置的基礎上,Spring 3.x 還擴展了基於 Java 類的配置。Spring Framework 增長了 Expression、Instructment、Tomcat、oxm 等組件,同時將原來的 Web 細分爲:Portlet、Servlet。
2.4 Spring 4.x
沿着 Spring 3.x 組件化的方向,4.x 繼續升級演進升級,Spring Framework 擴充了 Groovy、Messaging、Webmvc、Tiles二、Websocket 等功能組件。同時,Spring 還有條升級主線就是適配 Java 的版本,全面支持Java 8.0,支持 Lambda 表達式等。隨着 RESTful 架構風格被愈來愈多的用戶所採用,Spring 4.x 也提供了 RestController 等註解新特性。
2.5 Spring 5.x
軟件技術更新換代很是迅速,稍不留神就可能落後於時代,Spring 5.x 緊跟 Java 相關技術的更新迭代,不斷適配最新版本的 Java,同時不斷重構優化自身核心框架代碼,支持函數式、響應式編程模型。咱們說歷史有其必然律,曾經屠龍的勇士終將變成惡龍,近十年的升級演進讓 Spring 愈來愈強大的同時也變得異常複雜,曾經靠輕量化、易於使用等特色打敗了 EJB,現現在卻變得跟 EJB 同樣臃腫了,Spring 可否掙脫這個歷史的必然律嗎?
2.6 Spring Boot
老兵哥是從 2.x 開始加入 Spring 陣營的,期間跟隨 Spring 的升級演進一路走來,對它還算是熟悉瞭解的,這背後沉澱着十年左右的背景知識及使用經驗。但對於剛剛參加工做不久的新人來講,Spring 顯得太龐大、太複雜了。任何專業技能的精進都離不開長時間的學習和實踐,但現實告訴咱們,新人才是大部分企業中應用開發的主力人羣。可否適應環境變化知足這些新生力量的訴求,將決定 Spring 可否繼續穩坐 Java 應用開發框架的頭把交椅。
老兵哥近兩年在公司內部推廣微服務架構,微服務的實現方法有許多種,但關鍵要從用戶視角出發。如今九零後是主力開發人羣,完整的 Spring 技術棧對他們來講挑戰太大了,他們缺少足夠的動力學習如此繁雜的技術。這時候咱們必需要從技術視角轉換成產品視角,瞭解用戶的真實想法,下降他們學習使用 Spring 的難度。
在這個關鍵的時間點上,Spring 不忘初心,從新回到輕量化這個出發點上,採用約定優先配置的理念對複雜度作了封裝,對用戶屏蔽了許多實現細節。就像計算機的芯片技術異常複雜,但普通用戶不須要懂太多電子電路知識就可使用,如今新人們也不要掌握太多背景知識就可使用 Spring Boot 作開發了。這是咱們技術人廣泛缺少的產品思惟,常常遇見以複雜炫技的技術人,再牛的技術,若是不能被更多用戶使用,那也終將被淘汰。產品思惟就是站在用戶的視角看問題,往用戶方向多走一步。對於如此大致量的 Spring 來講,這不啻於涅槃再生。
考慮到咱們每一個人的工做學習狀況不一樣,平時遇到的問題也不一樣,本文內容沒法覆蓋全部人遇到的問題,歡迎你們留言提問,也歡迎關注「 IT老兵哥 」交流互動,謝謝!
本系列其餘文章索引以下:Spring 核心技術與產品理念剖析(下)