您好,登錄后才能下訂單哦!
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 擴展定制和培訓推廣。
一晃眼十五年過去了,從取代 EJB 的輕量級開發框架開始,到無比強大的生態圈,再到 Spring Boot\Spring Cloud 重新塑身成為云原生應用開發領域的首選框架。Spring 早已不是最初的模樣了,在它身上發生過無數變化,但唯一不變的是它仍舊穩坐 Java 開發框架領域的頭把交椅。或許大部分讀者都熟悉 Spring 的使用,但你知道它背后的核心技術有哪些嗎?這些年它都發生過哪些重大的變化?它演進至 Spring Boot/Spring Cloud 的原因是什么?它的成功源于哪些關鍵的產品設計理念?...... 熟悉 Spring 的使用僅僅是"知其然",唯有"知其所以然",我們才能真正融會貫通用好它。快來吧,千萬不要錯過!老兵用血汗經驗為你剖析那些風云變幻中的不變量:
Spring 背后的核心技術
Spring 演進發展的歷程
Spring Cloud 蝶變重生
Spring 的產品設計理念
Spring 的產品推廣策略
......?
適讀人群:開發、測試、架構、產品等
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、Tiles2、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 核心技術與產品理念剖析(下)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。