Spring是Java平台的一個開源的全棧應用程式框架和控制反轉容器實現。 該框架的一些核心功能理論上可用於任何Java應用,但Spring還為基於Java企業版平台構建的 Web 應用提供了大量的拓展支持。雖然Spring沒有直接實現任何的編程模型,但它已經在 Java社區中廣為流行,基本上完全代替了企業級JavaBeans(EJB)模型。
Spring框架以 Apache License 2.0 開源許可協議的形式發布,該框架最初由 Rod Johnson 以及 Juergen Hoeller 等人開發。
一、版本歷史
第一版由 Rod Johnson 開發,並在2002年10月發布在 Expert One-on-One J2EE Design and Development 一書中。2003年6月,Spring Framework 第一次發布在 Apache 2.0 許可證下。2004年3月,發布了里程碑的版本1.0,2004年9月以及2005年3月,又發布了新的里程碑版本。2006年,Spring Framework 獲得了 Jolt 生產力獎 和 JAX 創新獎。
2006年10月發布Spring 2.0,2007年11月 Spring 2.5,2009年12月 Spring 3.0,2011年 Spring 3.1,2013年11月 Spring 3.2.5,2013年12月發布了4.0版本。值得注意的是,Spring 4.0 版本中增加了對 Java SE 8, Groovy 2, Java EE 7 的一些方面以及 WebSocket 的支持。
2017年9月 Spring Framework 正式發布了 5.0 版本,此版本引入了 Spring WebFlux,一個高性能、響應式、異步的 Web 框架。Spring 5.0 重點加強了對函數式編程、響應式程序設計(reactive programming)的支持能力,是一個非常大的進步。
二、核心功能模塊
- 強大的基於 JavaBeans 的採用控制反轉(Inversion of Control,IoC)原則的配置管理,使得應用程式的組建更加簡易快捷。
- 一個可用於 Java EE 等運行環境的核心 Bean工廠。
- 資料庫事務的一般化抽象層,允許聲明式(Declarative)事務管理器,簡化事務的劃分使之與底層無關。
- 內建的針對 JTA 和單個 JDBC 數據源的一般化策略,使Spring的事務支持不要求 Java EE 環境,這與一般的 JTA 或者 EJB CMT 相反。
- JDBC 抽象層提供了有針對性的異常等級(不再從SQL異常中提取原始代碼),簡化了錯誤處理,大大減少了程式設計師的編碼量。再次利用JDBC時,你無需再寫出另一個'終止'(finally)模塊。並且面向 JDBC 的異常與 Spring 通用數據訪問對象(Data Access Object)異常等級相一致。
- 以資源容器,DAO 實現和事務策略等形式與 Hibernate,JDO 和 MyBatis 、SQL Maps 集成。利用控制反轉機制全面解決了許多典型的Hibernate集成問題。所有這些全部遵從 Spring 通用事務處理和通用數據訪問對象異常等級規範。
- 靈活的基於核心 Spring功能的MVC網頁應用程式框架。開發者通過策略接口將擁有對該框架的高度控制,因而該框架將適應於多種呈現(View)技術,例如JSP、FreeMarker、Velocity、Thymeleaf等。值得注意的是,Spring中間層可以輕易地結合於任何基於 MVC 框架的網頁層,例如 Struts、WebWork 或 Tapestry。
- 提供諸如事務管理等服務的AOP框架。
- 在設計應用程式 Model時,MVC模式(例如Struts)通常難於給出一個簡潔明了的框架結構。Spring 卻具有能夠讓這部分工作變得簡單的能力。程序開發員們可以使用Spring的JDBC抽象層重新設計那些複雜的框架結構。
三、從Bean開始
最早的1996年開始可以使用Java的Applet來開發Web應用,作為瀏覽器組件。但開發者們很快就發現這個新興的語言還能做更多的事情。同年12月,Sun公司發布了當時還名不見經傳但後來人盡皆知的 JavaBean 1.00-A 規範。
複雜的應用通常需要事務、安全、分布式等服務的支持,但JavaBean並未直接提供。所以到了 1998年 3 月,Sun公司發布了EJB1.0規範,該規範把Java組件的設計理念延伸到了伺服器端,並提供了許多必須的企業級服務,但他也不再像早期的JavaBean 那麼簡單了。實際上,除了名字叫 EJB Bean以外,其他的和 JavaBean關係不大了。
儘管現實中有很多系統是基於EJB構建的,但EJB從來沒有實現它最初的設想:簡化開發。EJB 的聲明式編程模型的確簡化了很多基礎架構層面的開發,例如事務和安全;但另一方面 EJB 在部署描述符和配套代碼實現等方面變得異常複雜。隨著時間的推移,很多開發者對 EJB 已經不再抱有幻想,開始尋求更簡潔的方法。
客觀地講,EJB 的發展甚至促進了基於 POJO 的編程模型。到了 EJB 3 規範發 布時,其他基於 POJO的開發架構已經成為事實的標準了,而Spring框架也就是在這樣的大環境下出現的。
四、Spring能給我們帶來什麼
4.1 Spring簡化開發的四個基本策略
- 基於POJO的輕量級和最小侵入性編程
- 通過依賴注入和面向接口松耦合
- 基於切面和慣性進行聲明式編程
- 通過切面和模板減少樣板式代碼
Spring主要通過:面向Bean(BOP)、依賴注入(DI)和面向切面(AOP)這三種方式來達成的。
AOP、IOC和DI之間的關係
4.2 BOP編程
Spring 是面向 Bean 的編程(Bean Oriented Programming, BOP),Bean 在Spring 中才是真正的主角。Bean 在 Spring 中作用就像 Object 對OOP的意義一樣,Spring 中沒有 Bean 也就沒有Spring存在的意義。Spring提供了IOC容器通過配置文件或者註解的方式來管理對象之間的依賴關係。
控制反轉(其中最常見實現方式叫做依賴注入(Dependency Injection,DI),還有一種方式叫「依賴查找」(Dependency Lookup,DL),她在 C++、Java、PHP 以及.NET 中都運用。在最早的Spring中是包含有依賴注入方法和依賴查詢的,但因為依賴查詢使用頻率過低,不久就被Spring移除了,所以在Spring中控制反轉也被直接稱作依賴注入),她的基本概念是:不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。容器 (在 Spring 框架中是 IOC 容器)負責將這些聯繫在一起。
在典型的 IOC 場景中,容器創建了所有對象,並設置必要的屬性將它們連接在一起,決定什麼時間調用方法。
4.3 依賴注入
Spring 設計的核心 org.springframework.beans包(架構核心是org.springframework.core包),它的設計目標是與JavaBean組件一起使用。這個包通常不是由用戶直接使用,而是由伺服器將其用作其他多數功能的底層中介。下一個最高級抽象是 BeanFactory 接口,它是工廠設計模式的實現,允許通過名稱創建和檢索對象。BeanFactory 也可以管理對象之間的關係。
BeanFactory 最底層支持兩個對象模型:
- 單例:提供了具有特定名稱的全局共享實例對象,可以在查詢時對其進行檢索。Singleton 是默認的也是最常用的對象模型。
- 原型:確保每次檢索都會創建單獨的實例對象。在每個用戶都需要自己的對象時,採用原型模式。
Bean 工廠的概念是 Spring作為IOC容器的基礎。IOC則將處理事情的責任從應用程式代碼轉移到框架。
4.4 AOP 編程
面向切面編程,即 AOP,是一種編程思想,它允許程式設計師對橫切關注點或橫切典型的職責分界線的行為(例如日誌和事務管理)進行模塊化。AOP的核心構造是方面(切面),它將那些影響多個類的行為封裝到可重用的模塊中。
AOP 和 IOC 是補充性的技術,它們都運用模塊化方式解決企業應用程式開發中的複雜問題。在典型的面向對象開發方式中,可能要將日誌記錄語句放在所有方法和 Java 類中才能實現日誌功能。在AOP方式中,可以反過來將日誌服務模塊化,並以聲明的方式將它們應用到需要日誌的組件上。當然,優勢就是Java類不需要知道日誌服務的存在,也不需要考慮相關的代碼。所以,用SpringAOP編寫的應用程式代碼是鬆散耦合的。
AOP 的功能完全集成到了 Spring 事務管理、日誌和其他各種特性的上下文中。
AOP 編程的常用場景有:Authentication(權限認證)、Auto Caching(自動緩存處理)、Error Handling (統一錯誤處理)、Debugging(調試信息輸出)、Logging(日誌記錄)、Transactions(事務處理) 等。
五、Spring5的系統架構
Spring 總共大約有 20個模塊,由1300多個不同的文件構成。而這些組件被分別整合在核心容器(Core Container)、AOP(Aspect Oriented Programming)和設備支持(Instrmentation)、數據訪問 及集成(Data Access/Integeration)、Web、報文發送(Messaging)、Test,6 個模塊集合中。以下是 Spring 5 的模塊結構圖: