程式設計師都很崇拜技術大神,很大一部分是因為他們發現和解決問題的能力,特別是線上出現緊急問題時,總是能夠快速定位和解決。
一方面,他們有深厚的技術基礎,對應用的技術知其所以然,另一方面,在採坑的過程中不斷總結,積累了很多經驗。
相信大家都使用過Spring,有些人瞭解它的核心:IOC和AOP,但只是瞭解它們的基本概念、使用了反射和動態代理,關於如何管理物件、代理的具體實現瞭解的比較淺。
有些人使用Spring MVC,使用Spring整合資料庫、事務、訊息佇列以簡化操作,但對整合的具體設計思路和實現瞭解的也比較淺。
我也這一塊也比較菜,所以,後面的一段時間會梳理和總結Spring相關的技術原理,以「Spring技術內幕:深入解析Spring架構與設計原理」書籍為核心,結合自己的使用經驗和疑問,以及網路上大牛的文章,來補足自己這方面的缺失。
這本書作者是計文柯,以Spring原始碼為依託,從巨集觀上揭示了Spring的設計思路和架構思想,從微觀上剖析了Spring各功能模組的實現原理和執行機制。一方面希望讀者能通過深入瞭解Spring的底層機制來更好地解決實際開發中遇到的各種難題,另一方面是希望讀者能吸收Spring設計和實現中的優秀方法和思想。
全書共三部分,分別闡述了Spring的核心、元件和應用。第一部分詳細分析了IOC容器和AOP實現,第二部分闡述了基於Spring IOC容器和AOP的Java EE元件在Spring中的實現,第三部分講述了一些基於Spring的典型應用的實現。
本篇先對設計理念和整體架構做個概述,從整體上看看Spring的設計目標和架構,通過本篇,你會了解到:
- Spring的設計目標
- Spring的整體架構
- Spring的各個子專案介紹
設計目標
簡單來說,Spring的設計目標是為我們提供一個一站式的輕量級應用開發平臺,抽象了應用開發中遇到的共性問題。
作為平臺,它考慮到了企業應用資源的使用,比如資料的持久化、資料整合、事務處理、訊息中介軟體、分散式式計算等高效可靠處理企業資料方法的技術抽象。
輕量級是相對於傳統J2EE而言的,傳統的J2EE開發,需要依賴按照J2EE規範實現的J2EE應用伺服器,設計和實現時,需要遵循一系列的介面標準,這種開發方式耦合性高,使應用在可測試性和部署上都有影響,對技術的理解和要求相對較高。
使用Spring進行開發,對開發人員比較輕量,可以使用POJO和JavaBean的開發方式,使應用面向介面開發,充分支援了物件導向的設計方法。通過IOC容器減少了直接耦合,通過AOP以動態和非侵入的方式增加了服務的功能,為靈活選取不同的服務實現提供了基礎,這也是Spring的核心。
開發過程中的共性問題,Spring封裝成了各種元件,而且Spring通過社群,形成了一個開放的生態系統,比如Spring Security就是來源於一個社群貢獻Acegi.
整體架構
從總體來看,Spring分為3層,最底層是核心層,包括IOC、AOP等核心模組,中間層是封裝的JavaEE服務、作為中間的驅動元件,最上層是各個應用。
下圖是Spring官網的一個架構圖,介紹下其組成部分:
核心容器
由spring-core、spring-beans、spring-context、spring-context-support和spring-expression模組組成:
spring-core和spring-beans提供框架的基礎部分,包括IOC功能,BeanFactory是一個複雜的工廠模式的實現,將配置和特定的依賴從實際程式邏輯中解耦。
context模組建立在core和beans模組的基礎上,增加了對國際化的支援、事件廣播、資源載入和建立上下文,ApplicationContext是context模組的重點。
spring-context-support提供對常見第三個庫的支援,整合到spring上下文中,比如快取(ehcache,guava)、通訊(javamail)、排程(commonj,quartz)、模板引擎等(freemarker,velocity)。
spring-expression模組提供了一個強大的表示式語言用來在執行時查詢和操作物件圖,這種語言支援對屬性值、屬性引數、方法呼叫、陣列內容儲存、集合和索引、邏輯和算數操作及命名變數,並且通過名稱從spring的控制反轉容器中取回物件。
AOP和伺服器工具
spring-aop模組提供面向切面程式設計實現,單獨的spring-aspects模組提供了aspectj的整合和適用。
spring-instrument提供一些類級的工具支援和ClassLoader級的實現,用於伺服器。spring-instrument-tomcat針對tomcat的instrument實現。
訊息元件
spring框架4包含了spring-messaging模組,從spring整合專案中抽象出來,比如Messge、MessageChannel、MessageHandler及其他用來提供基於訊息的基礎服務。
資料訪問/整合
資料訪問和整合層由JDBC、ORM、OXM、JMS和事務模組組成。
spring-jdbc模組提供了不需要編寫冗長的JDBC程式碼和解析資料庫廠商特有的錯誤程式碼的JDBC抽象出。
spring-tx模組提供可程式設計和宣告式事務管理。
spring-orm模組提供了領先的物件關係對映API整合層,如JPA、Hibernate等。
spring-oxm模組提供抽象層用於支援Object/XML maping的實現,如JAXB、XStream等。
spring-jms模組包含生產和消費訊息的功能,從Spring4.1開始提供整合spring-messaging模組。
Web
Web層包含spring-web、spirng-webmvc、spring-websocket和spring-webmvc-portlet模組組成。
spring-web模組提供了基本的面向web開發的整合功能,例如多檔案上傳、使用servert listeners和web開發應用程式上下文初始化IOC容器。也包含HTTP客戶端以及spring遠端訪問的支援的web相關部分。
spring-webmvc包含spring的model-view-controller和REST web services 實現的Web應用程式。
spring-webmvc-portlet模組提供了MVC模式的portlet實現,protlet與Servlet的最大區別是請求的處理分為action和render階段,在一個請求中,action階段只執行一次,但render階段可能由於使用者的瀏覽器操作而被執行多次。
測試
spring-test模組支援通過組合Junit或TestNG來進行單元測試和整合測試,提供了連續的載入ApplicationContext並且快取這些上下文。
各個子專案介紹
從配置到安全,從web應用到大資料——無論您的應用程式需要什麼樣的基礎設施,都有一個Spring專案來幫助您構建它,Spring是模組化的設計。
Spring Boot
簡化新Spring應用的初始搭建以及開發過程,使用特定的方式進行配置,使開發人員不再需要定義樣板化的配置,實現快速開發。
Spring Cloud
為分散式系統開發提供工具集,基於Spring Boot,為基於JVM的雲應用開發中的配置管理、服務發現、斷路器、智慧路由、控制匯流排、全域性鎖、決策競選、分散式會話、叢集狀態管理等操作提供了一種簡單的開發方式,其下有很多子專案:
- 分散式/版本化配置:Spring Cloud Config
- 服務註冊和發現:Netflix Eureka 或者 Spring Cloud Eureka(對前者的二次封裝)
- 路由:Spring Cloud Zuul,基於 Netflix Zuul
- service - to - service呼叫:Spring Cloud Feign
- 負載均衡:Spring Cloud Ribbon 基於 Netflix Ribbon 實現
- 斷路器:Spring Cloud Hystrix
- 分散式訊息傳遞:Spring Cloud Bus
Spring Cloud Data Flow
Data flow 是一個用於開發和執行大範圍資料處理、批量運算、持續運算的統一程式設計模型和託管服務。
Spring Cloud Data Flow 是基於原生雲對Spring XD的重新設計,專案目標是簡化大資料應用的開發。Spring XD的流處理和批處理模組的重構分別基於spring boot的stream和task/batch的微服務程式。這些程式原生的支援像 Apache YARN、Apache Mesos和Kubernetes等現代執行環境,都是自動部署單元。
Spring Data
資料訪問模組,提供了對JDBC及ORM很好的支援,隨著NOSQL和BigData的興起,出現了越來越多的新技術,比如非關係型資料庫、MapReduce框架,為了讓spring開發者能更方便地使用這些新技術,通過Spring Data,開發者可以用Spring提供的相對一致的方式訪問位於不同型別的資料儲存中的資料。
Spring Integration
在企業軟體開發過程中,經常會遇到與外部系統整合,Spring Integration為Spring程式設計模型提供了一個支援企業整合模式的擴充套件,在應用程式中提供輕量級的訊息機制,通過宣告式的介面卡與外部系統進行整合。
Spring Integraton中有幾個基本的概念:
- Message:帶有後設資料的Java物件;
- Channel:傳遞訊息的管道;
- Message Endpoint:訊息的處理端,在處理端可以對訊息進行轉換、路由、過濾、拆分、聚合等操作;
還可以使用Channel Adapter,這是應用程式與外界互動的地方,輸入是Inbound、輸出則是Outbound,可選的連線型別有很多,比如AMQP、JDBC、Web Services、FTP、JMS、XMPP、多種NoSQL資料庫等等。只需通過簡單的配置檔案就能將所有這些東西串聯在一起,實現複雜的整合工作。
Spring Batch
簡化及優化大量資料的批處理操作,支援事務、併發、流程、監控、縱向和橫向擴充套件,提供統一的介面管理和任務管理。
例如它提供了很多方法來讀取大型的檔案(比如1GB的CSV、XML檔案),在資料庫中載入或更新幾萬甚至幾十萬條記錄,如果直接select出所有記錄,以至於拖垮整個系統,而使用了Spring Batch,框架會幫助他每次撈取一部分記錄進行分頁,在更新時分批進行提交。
Spring Security
一款Spring的認證和安全工具。其前身是Acegi,目標是為Spring應用提供一個安全服務,比如使用者認證、授權等。
它使用Servlet規範中的Filter保護Web請求並限制URL級別的訪問,還能夠使用Spring AOP保護方法呼叫——藉助於物件代理和使用通知,能夠確保只有具備適當許可權的使用者才能訪問安全保護的方法。
它非常靈活,能夠基於各種資料儲存來認證使用者。它內建了多種常見的使用者儲存場景,如記憶體、關係型資料庫以及LDAP,還可以編寫並插入自定義的使用者儲存實現。
Spring HATEOAS
先來理解HATEOAS:大家都聽過過REST,它的定位為「分散式超媒體應用」的架構風格,文中提到了HATEOAS(Hypermedia as the engine of application state)的概念,超媒體即應用狀態引擎,即返回結果中提供連結,連向其他API方法,使得使用者不查文件,也知道下一步應該做什麼。
比如獲取一篇文章,非HATEOAS的響應例子是:
GET /posts/1 HTTP/1.1
Connection: keep-alive
Host: blog.example.com
{
"id" : 1,
"body" : "My first blog post",
"postdate" : "2015-05-30T21:41:12.650Z"
}
複製程式碼
而HATEOAS的響應例子是:
{
"id" : 1,
"body" : "My first blog post",
"postdate" : "2015-05-30T21:41:12.650Z",
"links" : [
{
"rel" : "self",
"href" : http://blog.example.com/posts/1,
"method" : "GET"
}
]
}
複製程式碼
為了簡化簽入或獲取超連結等操作,Spring HATEOAS提供了相關的支援。
Spring Rest DOCS
可以生成準確可讀的RESTful Service文件,Spring 官方文件都是用Spring REST Docs生成的。
基於單元測試生成文件片段,不會侵入到原始碼中,所以就不會使得原始碼變得越來越臃腫,支援markdown,修改一行配置程式碼即可支援生成 MarkDown 語法的文件片段。
預設的,在構建的時候,會首先執行單元測試,便生成了文件片段,然後在打包時,通過新增 asciidoctor-maven-plugin 外掛即可生成最終的文件,只要是規範的開發過程,文件都會隨版本的每次釋出而自動更新。
Spring Social
使用 Spring Social 的最大好處在於它已經提供了對主流社交網站的支援,只需要簡單配置即可,對於一些不太常用的社交網站,也可以從社群中找到相應的元件。
Spring AMQP
基於Spring框架的AMQP訊息解決方案,提供模板化的傳送和接收訊息的抽象層,提供基於訊息驅動的POJO,使在Spring應用中使用AMQP訊息伺服器變得更為簡單,SpringSource旗下的Rabbit MQ就是一個開源的基於AMQP的訊息伺服器。
Spring Web Flow
Spring Web Flow是Spring MVC 的擴充套件,它支援開發基於流程的應用程式。它將流程的定義與實現流程行為的類和檢視分離開來,具有同時處理多個HTTP請求、管理會話狀態、資料事務處理,支援AJAX來構建豐富的客戶端體驗,並且提供對JSF的支援。
Spring LDAP
Spring LDAP是一個用於操作LDAP的Java框架。它是基於Spring的JdbcTemplate模式,能夠幫助開發人員簡化操作。
Spring Session
Spring Session提供了一套建立和管理Servlet HttpSession的方案。Spring Session提供了叢集Session功能,預設採用外接的Redis來儲存Session資料,以此來解決Session共享的問題。
Spring Shell
Spring Shell提供互動式的Shell,可以讓你使用簡單的基於Spring的程式設計模型來開發命令。
Spring Kafka
spring for kafka對原生的kafka client consumer的封裝與整合。
Spring Statemachine
它的主要功能是幫助開發者簡化狀態機的開發過程,讓狀態機結構更加層次化。
Spring IO Platform
可以認為是一個依賴維護平臺,該平臺將相關依賴匯聚到一起,針對每個依賴,都提供了一個版本號。
主要是解決依賴版本衝突問題,在使用Spring的時候,經常會使用到第三方庫,一般大家都是根據經驗挑選一個版本號或挑選最新的,風向較大,很容易衝突。
Spring IO Platform能很好地解決這些問題,我們在新增第三方依賴的時候,不需要寫版本號,它能夠自動幫我們挑選一個最優的版本。
歡迎掃描下方二維碼,關注我的個人微信公眾號,檢視更多文章 ~