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