前言
Spring Framework 作為一個(gè)優(yōu)秀的開(kāi)源框架各谚,是為了解決企業(yè)應(yīng)用程序開(kāi)發(fā)復(fù)雜性而創(chuàng)建的莺债∽叹酰框架的主要優(yōu)勢(shì)之一就是其分層架構(gòu),分層架構(gòu)允許您選擇使用哪一個(gè)組件齐邦,同時(shí)為 J2EE 應(yīng)用程序開(kāi)發(fā)提供集成的框架椎侠。
現(xiàn)在的Spring已然發(fā)展成了一個(gè)平臺(tái),引用Spring官網(wǎng)的原話:
From configuration to security, web apps to big data – whatever the infrastructure needs of your application may be, there is a Spring Project to help you build it. Start small and use just what you need – Spring is modular by design.
Main Projects:
- Spring Framework
- Spring Boot
- Spring Cloud
- Spring Security
- Spring Data
- ...
這里只列出了最近比較火的 Spring Project措拇,更多Project 請(qǐng)參考:https://spring.io/projects
本篇著重介紹 Spring Framework整體架構(gòu)我纪,希望能改對(duì) Spring Framework框架有一個(gè)初步的全面的認(rèn)識(shí),并且學(xué)習(xí)其架構(gòu)設(shè)計(jì)方面的一些理念和方法丐吓。
Spring Framework源碼地址:https://github.com/spring-projects/spring-framework
Spring Framework的整體架構(gòu)
Spring Framework總共有十幾個(gè)組件浅悉,其中核心組件只有三個(gè):Core、Context 和 Beans券犁。
Spring Framework 3.x 的總體架構(gòu)圖
組成 Spring Framework的每個(gè)模塊(或組件)都可以單獨(dú)存在术健,或者與其他一個(gè)或多個(gè)模塊聯(lián)合實(shí)現(xiàn)。每個(gè)模塊的功能如下:
- Spring Core(核心容器):核心容器提供 Spring 框架的基本功能粘衬。核心容器的主要組件是 BeanFactory苛坚,它是工廠模式的實(shí)現(xiàn)比被。BeanFactory 使用控制反轉(zhuǎn) (IOC) 模式將應(yīng)用程序的配置和依賴性規(guī)范與實(shí)際的應(yīng)用程序代碼分開(kāi)。
- Spring Context(上下文):Spring 上下文是一個(gè)配置文件泼舱,向 Spring 框架提供上下文信息等缀。Spring 上下文包括企業(yè)服務(wù),例如:JNDI娇昙、EJB尺迂、電子郵件、國(guó)際化冒掌、校驗(yàn)和調(diào)度功能噪裕。
- Spring AOP:通過(guò)配置管理特性,Spring AOP 模塊直接將面向方面的編程功能集成到了 Spring 框架中股毫。所以膳音,可以很容易地使 Spring 框架管理的任何對(duì)象支持 AOP。Spring AOP 模塊為基于 Spring 的應(yīng)用程序中的對(duì)象提供了事務(wù)管理服務(wù)铃诬。通過(guò)使用 Spring AOP祭陷,不用依賴 EJB 組件,就可以將聲明性事務(wù)管理集成到應(yīng)用程序中趣席。
- Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結(jié)構(gòu)兵志,可用該結(jié)構(gòu)來(lái)管理異常處理和不同數(shù)據(jù)庫(kù)供應(yīng)商拋出的錯(cuò)誤消息。異常層次結(jié)構(gòu)簡(jiǎn)化了錯(cuò)誤處理宣肚,并且極大地降低了需要編寫(xiě)的異常代碼數(shù)量(例如打開(kāi)和關(guān)閉連接)想罕。Spring DAO 的面向 JDBC 的異常遵從通用的 DAO 異常層次結(jié)構(gòu)。
- Spring ORM:Spring 框架插入了若干個(gè) ORM 框架霉涨,從而提供了 ORM 的對(duì)象關(guān)系工具按价,其中包括 JDO、Hibernate 和 iBatis SQL Map笙瑟。所有這些都遵從 Spring 的通用事務(wù)和 DAO 異常層次結(jié)構(gòu)楼镐。
- Spring Web 模塊:Web 上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于 Web 的應(yīng)用程序提供了上下文逮走。所以鸠蚪,Spring 框架支持與 Jakarta Struts 的集成今阳。Web 模塊還簡(jiǎn)化了處理多部分請(qǐng)求以及將請(qǐng)求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?/li>
- Spring MVC 框架:MVC 框架是一個(gè)全功能的構(gòu)建 Web 應(yīng)用程序的 MVC 實(shí)現(xiàn)师溅。通過(guò)策略接口,MVC 框架變成為高度可配置的盾舌,MVC 容納了大量視圖技術(shù)墓臭,其中包括 JSP、Velocity妖谴、Tiles窿锉、iText 和 POI酌摇。
從圖中可以看出,IOC 的實(shí)現(xiàn)包 spring-beans 和 AOP 的實(shí)現(xiàn)包 spring-aop 也是整個(gè)框架的基礎(chǔ)嗡载,而 spring-core 是整個(gè)框架的核心窑多,基礎(chǔ)的功能都在這里。
在此基礎(chǔ)之上洼滚,spring-context 提供上下文環(huán)境埂息,為各個(gè)模塊提供粘合作用。
在 spring-context 基礎(chǔ)之上提供了 spring-tx 和 spring-orm包遥巴,而web部分的功能千康,都是要依賴spring-web來(lái)實(shí)現(xiàn)的。
Spring Framework 4.x 的系統(tǒng)架構(gòu)圖
Spring Framework 4.x對(duì)比Spring Framework 3.2.x的系統(tǒng)架構(gòu)變化:
從圖中可以看出铲掐,總體的層次結(jié)構(gòu)沒(méi)有太大變化拾弃,變化的是 Spring 4.0.3去掉了 struts 模塊(spring-struts包)。現(xiàn)在的 Spring mvc的確已經(jīng)足夠優(yōu)秀了摆霉,大量的 web 應(yīng)用均已經(jīng)使用了 Spring mvc豪椿。而 struts1.x 的架構(gòu)太落后了,struts2.x 是 struts 自身提供了和 Spring 的集成包斯入,但是由于之前版本的 struts2 存在很多致命的安全漏洞砂碉,所以,大大影響了其使用度刻两,好在最新的2.3.16版本的 struts 安全有所改善增蹭,希望不會(huì)再出什么大亂子。
web 部分去掉了 struts 模塊磅摹,但是增加 WebSocket 模塊(spring-websocket包)滋迈,增加了對(duì) WebSocket、SockJS 以及 STOMP 的支持户誓,它與 JSR-356 Java WebSocket API 兼容饼灿。另外,還提供了基于 SockJS(對(duì) WebSocket 的模擬)的回調(diào)方案帝美,以適應(yīng)不支持 WebSocket 協(xié)議的瀏覽器碍彭。
同時(shí),增加了 messaging 模塊(spring-messaging)悼潭,提供了對(duì) STOMP 的支持庇忌,以及用于路由和處理來(lái)自 WebSocket 客戶端的 STOMP 消息的注解編程模型。spring-messaging 模塊中還 包含了 Spring Integration 項(xiàng)目中的核心抽象類(lèi)舰褪,如 Message皆疹、MessageChannel、MessageHandler占拍。
如果去看源代碼的話略就,還可以發(fā)現(xiàn)還有一個(gè)新增的包捎迫,加強(qiáng)了 beans 模塊,就是 spring-beans-groovy表牢。應(yīng)用可以部分或完全使用 Groovy 編寫(xiě)窄绒。借助于 Spring 4.0,能夠使用 Groovy DSL 定義外部的 Bean 配置崔兴,這類(lèi)似于 XML Bean 聲明颗祝,但是語(yǔ)法更為簡(jiǎn)潔。使用Groovy還能夠在啟動(dòng)代碼中直接嵌入Bean的聲明恼布。
還有一些:
- 刪除過(guò)時(shí)的包和方法螺戳。具體API變動(dòng)可以參考變動(dòng)報(bào)告,第三方類(lèi)庫(kù)至少使用2010/2011年發(fā)布的版本折汞,尤其是Hibernate 3.6+, EhCache 2.1+, Quartz 1.8+, Groovy 1.8+, and Joda-Time 2.0+倔幼。Hibernate Validator要求使用4.3+,Jackson 2.0+爽待。
- Java 8支持损同。當(dāng)然也支持Java6和Java7,但最好在使用Spring框架3.X或4.X時(shí)鸟款,將JDK升級(jí)到Java7膏燃,因?yàn)橛行┌姹局辽傩枰狫ava7。
- Java EE 6和7何什。使用Spring4.x時(shí)Java EE版本至少要6或以上组哩,且需要JPA 2.0和Servlet 3.0 的支持,所以服務(wù)器处渣,web容器需要做相應(yīng)的升級(jí)伶贰。一個(gè)更具前瞻性的注意是,Spring4.0支持J2EE 7的適用級(jí)規(guī)范罐栈,比如JMS 2.0黍衙, JTA 1.2, JPA 2.1荠诬, Bean Validation 1.1和JSR-236并發(fā)工具包琅翻,在選擇這些jar包時(shí)需要注意版本。
- 使用Groovy DSL定義外部Bean柑贞。
- 核心容器提升方椎。
- 支持Bean的泛型注入,比如:@Autowired Repository<Customer> customerRepository
- 使用元注解開(kāi)發(fā)暴露指定內(nèi)部屬性的自定義注解凌外。
- 通過(guò) @Ordered注解或Ordered 接口對(duì)注入集合或數(shù)組的 Bean 進(jìn)行排序辩尊。
- @Lazy 注解可以用在注入點(diǎn)或 @Bean 定義上涛浙。
- 為開(kāi)發(fā)者引入 @Description 注解康辑。
- 引入 @Conditional 注解進(jìn)行有條件的 Bea n過(guò)濾摄欲。
- 基于 CGLIB 的代理類(lèi)不需要提供默認(rèn)構(gòu)造器,因?yàn)?Spring 框架將 CGLIB 整合到內(nèi)部了疮薇。
- 框架支持時(shí)區(qū)管理胸墙,比如 LocalContext。
- Web提升按咒。
- 增加新的 @RestController 注解迟隅,這樣就不需要在每個(gè) @RequestMapping 方法中添加 @ResponseBody 注解。
- 添加 AsyncRestTemplate励七,在開(kāi)發(fā) REST 客戶端時(shí)允許非阻塞異步支持智袭。
- 為 Spring MVC 應(yīng)用程序開(kāi)發(fā)提供全面的時(shí)區(qū)支持。
- WebSocket掠抬,SockJS 和 STOMP 消息吼野。
- 測(cè)試提升。
- spring-test 模塊里的幾乎所有注解都能被用做元注解去創(chuàng)建自定義注解两波,來(lái)減少跨測(cè)試集時(shí)的重復(fù)配置瞳步。
- 活躍的 bean 定義配置文件可以編程方式解析。
- spring-core 模塊里引入一個(gè)新的 SocketUtils 類(lèi)腰奋,用于掃描本地可使用的 TCP 和 UDP 服務(wù)端口单起。一般用于測(cè)試需要 socket 的情況,比如測(cè)試開(kāi)啟內(nèi)存 SMTP 服務(wù)劣坊,F(xiàn)TP 服務(wù)嘀倒,Servlet 容器等。
- 由于 Spring4.0 的原因局冰,org.springframework.mock.web 包現(xiàn)在基于 Servlet 3.0 API括儒。
關(guān)于Spring 4.x 新增特性可以參考 What’s New in Spring Framework 4.x
Spring 的設(shè)計(jì)理念
Spring 是面向 Bean 的編程(BOP, Bean Oriented Programming),Bean 在 Spring 中才是真正的主角锐想。Bean 在 Spring 中作用就像 Object 對(duì) OOP 的意義一樣帮寻,沒(méi)有對(duì)象的概念就像沒(méi)有面向?qū)ο缶幊蹋琒pring 中沒(méi)有 Bean 也就沒(méi)有 Spring 存在的意義赠摇。Spring 提供了 IOC 容器通過(guò)配置文件或者注解的方式來(lái)管理對(duì)象之間的依賴關(guān)系龟糕。
控制反轉(zhuǎn)模式(也稱作依賴性介入)的基本概念是:不創(chuàng)建對(duì)象,但是描述創(chuàng)建它們的方式褐墅。在代碼中不直接與對(duì)象和服務(wù)連接樱调,但在配置文件中描述哪一個(gè)組件需要哪一項(xiàng)服務(wù)。容器 (在 Spring 框架中是 IOC 容器) 負(fù)責(zé)將這些聯(lián)系在一起洽故。
在典型的 IOC 場(chǎng)景中贝攒,容器創(chuàng)建了所有對(duì)象,并設(shè)置必要的屬性將它們連接在一起时甚,決定什么時(shí)間調(diào)用方法隘弊。
面向切面編程
面向切面編程哈踱,即 AOP(Aspect Oriented Programming),是一種編程技術(shù)梨熙,它允許程序員對(duì)橫切關(guān)注點(diǎn)或橫切典型的職責(zé)分界線的行為(例如日志和事務(wù)管理)進(jìn)行模塊化开镣。AOP 的核心構(gòu)造是方面,它將那些影響多個(gè)類(lèi)的行為封裝到可重用的模塊中咽扇。
AOP 和 IOC 是補(bǔ)充性的技術(shù)邪财,它們都運(yùn)用模塊化方式解決企業(yè)應(yīng)用程序開(kāi)發(fā)中的復(fù)雜問(wèn)題。在典型的面向?qū)ο箝_(kāi)發(fā)方式中质欲,可能要將日志記錄語(yǔ)句放在所有方法和 Java 類(lèi)中才能實(shí)現(xiàn)日志功能树埠。在 AOP 方式中,可以反過(guò)來(lái)將日志服務(wù)模塊化嘶伟,并以聲明的方式將它們應(yīng)用到需要日志的組件上弥奸。當(dāng)然,優(yōu)勢(shì)就是 Java 類(lèi)不需要知道日志服務(wù)的存在奋早,也不需要考慮相關(guān)的代碼盛霎。所以,用 Spring AOP 編寫(xiě)的應(yīng)用程序代碼是松散耦合的耽装。
AOP 的功能完全集成到了 Spring 事務(wù)管理愤炸、日志和其他各種特性的上下文中。
IOC 容器
Spring 設(shè)計(jì)的核心是 org.springframework.beans 包掉奄,它的設(shè)計(jì)目標(biāo)是與 JavaBean 組件一起使用规个。這個(gè)包通常不是由用戶直接使用,而是由服務(wù)器將其用作其他多數(shù)功能的底層中介姓建。下一個(gè)最高級(jí)抽象是 BeanFactory 接口诞仓,它是工廠設(shè)計(jì)模式的實(shí)現(xiàn),允許通過(guò)名稱創(chuàng)建和檢索對(duì)象速兔。BeanFactory 也可以管理對(duì)象之間的關(guān)系墅拭。
BeanFactory 支持兩個(gè)對(duì)象模型:
- 單例 模型提供了具有特定名稱的對(duì)象的共享實(shí)例,可以在查詢時(shí)對(duì)其進(jìn)行檢索涣狗。Singleton 是默認(rèn)的也是最常用的對(duì)象模型谍婉。對(duì)于無(wú)狀態(tài)服務(wù)對(duì)象很理想。
- 原型 模型確保每次檢索都會(huì)創(chuàng)建單獨(dú)的對(duì)象镀钓。在每個(gè)用戶都需要自己的對(duì)象時(shí)穗熬,原型模型最適合。
bean 工廠的概念是 Spring 作為 IOC 容器的基礎(chǔ)丁溅。IOC 將處理事情的責(zé)任從應(yīng)用程序代碼轉(zhuǎn)移到框架唤蔗。
結(jié)束!