歡迎來到本篇文章!在這裡,我將帶領大家快速學習 Spring 的基本概念,並解答兩個關鍵問題:什麼是 Spring,以及為什麼學習 Spring。 廢話少說,下麵,我們開始吧! ...
前言
歡迎來到本篇文章!在這裡,我將帶領大家快速學習 Spring 的基本概念,並解答兩個關鍵問題:什麼是 Spring,以及為什麼學習 Spring。
廢話少說,下麵,我們開始吧!
Spring 官方文檔:https://docs.spring.io/spring-framework/docs/5.2.24.RELEASE/spring-framework-reference/
為什麼需要學習 Spring?
- 簡化我們的企業級應用程式的開發,提升我們的開發效率。
- 學 Java 的路上不得不學 Spring,不學直接用 Spring Boot 是可以,開箱即用,但是很難學懂,可能只是會用,不能知其然而知其所以然。
- 面試會問的啊!工作會用的啊!所以需要學嘛!OK!
Spring 這個詞,指的是什麼?
Spring
這個術語在不同的上下文中有不同的含義。它可以用來指代 Spring Framework
項目本身,這是夢開始的地方。
後來隨著時間的推移,其他基於 Spring Framework
構建的項目也相繼出現。當人們說 Spring
時,通常指整個項目家族。不過,在本系列中,我們就只指代它本身,即 Spring Framework
本身。
Spring Framework
被分為多個模塊,應用程式可以選擇需要哪些模塊。核心容器模塊包括配置模型和依賴註入機制等內容。除此之外,Spring Framework
還為不同類型應用架構提供了基礎支持,包括消息傳遞、事務數據和持久化以及 Web 開發等領域,並且同時提供了基於 Servlet
的 Spring MVC Web
框架和並行運行的 Spring WebFlux
響應式 Web 框架。
Spring 的模塊
實際上,Spring Framework
大約由 20 個模塊組成。這些模塊分為核心容器、數據訪問/集成、Web、AOP(面向切麵編程)、儀錶板、消息和測試等。如官網上給出的這張圖所示:
Core Container(核心模塊)
當我們談論 Spring 的核心容器時,我們指的是一些模塊,它們共同構成了這個框架的基礎。這些模塊包括 spring-core
、spring-beans
、spring-context
、spring-context-support
和 spring-expression
。
首先,讓我們來瞭解一下 spring-core
和 spring-beans
模塊。它們提供了一些基本功能,其中最重要的是「IoC(控制反轉)」和「依賴註入」。簡單來說,IoC 允許我們將對象的創建和管理交給框架來處理,而不是我們自己手動創建和管理。依賴註入則是一種將對象之間的依賴關係註入到它們之間的過程,這樣可以實現對象之間的解耦。
另外,BeanFactory
是一個工廠模式的複雜實現,它的作用是消除編寫單例模式的需要,並且允許我們將對象的配置和規範與實際的程式邏輯分離開來。
接下來是 Context
(spring-context
)模塊,它是在 Core
和 Beans
模塊的基礎上構建的。Context
模塊提供了一種類似於 JNDI(Java命名和目錄介面)註冊表的方式來訪問對象。除了繼承 Beans
模塊的功能外,Context
模塊還添加了對國際化、事件傳播、資源載入等功能的支持。它還能夠通過 Servlet 容器等方式透明地創建上下文。此外,Context
模塊還支持一些 Java EE 特性,如 EJB(企業級 Java Bean)、JMX(Java管理擴展)和基本的遠程處理。在 Context
模塊中,ApplicationContext
介面是重點關註的對象。另外,spring-context-support
模塊為將常見的第三方庫集成到 Spring 應用程式上下文中提供了支持,尤其是在緩存(EhCache、JCache)和調度(CommonJ、Quartz)方面。
最後,我們有 spring-expression
模塊,它提供了一個強大而靈活的表達式語言,用於在運行時查詢和操作對象圖(object graph)。該語言是 JSP 2.1 規範中統一表達式語言(unified EL)的擴展。它支持設置和獲取屬性值、屬性賦值、方法調用、訪問數組、集合和索引器的內容,以及邏輯和算術運算符、命名變數等。通過 Spring IoC
容器,我們還可以按名稱檢索對象。此外,該表達式語言還支持列表投影、選擇和常見的列表聚合操作。
AOP 和 Instrumentation
spring-aop
模塊是 Spring 框架中用於實現面向切麵編程的一部分,它遵循 AOP Alliance 標準。
那麼什麼是面向切麵編程呢?簡單來說,它允許我們在代碼中定義方法的攔截器和切入點,從而將某些功能與實際業務邏輯分離開來,以實現更清晰的代碼結構和更好的模塊化。舉個例子,比如當我們需要在代碼中引入一些日誌記錄、安全性檢查、性能監控的代碼,那麼這些代碼就是橫切關註點,我們可以使用 AOP 來實現這些代碼的引入,而不是將這些代碼分散到各個業務邏輯中。通過使用 AOP,我們可以將這些通用的橫切關註點定義為切麵,並將它們應用到適當的方法上,從而實現代碼的解耦和重用。
此外,Spring 還提供了單獨的 spring-aspects
模塊,用於與 AspectJ 進行集成。AspectJ 是一個功能強大的 AOP 框架,通過與 Spring 的集成,我們可以利用 AspectJ 的更高級功能來實現更複雜的切麵編程。
另外還有一個模塊叫做 spring-instrument
,它提供了類儀錶化(instrumentation)的支持和類載入器實現,在某些應用伺服器中可以使用。這個模塊的作用是提供一些工具和機制,以便在運行時對類進行修改和增強,從而實現一些特定的需求。例如,spring-instrument-tomcat
模塊是針對 Tomcat 伺服器的特定實現,它提供了用於儀錶化的代理機制。
Messaging
Spring 4 引入了一個名為 spring-messaging
的模塊,它包含了 Spring Integration 項目的核心抽象,例如 Message
、MessageChannel
、MessageHandler
等等。這個模塊的目的是提供消息傳遞應用程式的基礎支持。
通過 spring-messaging
模塊,我們可以構建基於消息傳遞的應用程式,其中不同組件之間通過消息進行通信。以下是一些關鍵概念和功能:
Message
:消息是應用程式中傳遞的數據單元。它可以包含有關消息內容和元數據的信息。MessageChannel
:消息通道是消息在應用程式中傳遞的路徑。它充當發送者和接收者之間的中介。MessageHandler
:消息處理器是負責接收和處理消息的組件。它可以執行特定的業務邏輯或轉發消息給其他組件。
spring-messaging
模塊還引入了一組註解,用於將消息映射到方法,類似於 Spring MVC 中基於註解的編程模型。這使得我們可以通過簡單的註解來定義消息的處理方式,讓代碼更加清晰和易於理解。
Data Access/Integration
當我們處理數據時,Spring 的數據訪問/集成層提供了一些模塊,以幫助我們更輕鬆地與資料庫和其他數據源進行交互。
spring-jdbc
模塊簡化了與資料庫進行交互的過程。它提供了一個抽象層,讓我們可以使用更簡單、更易於理解的代碼來執行資料庫操作,而不必處理繁瑣的細節。spring-tx
模塊支持事務管理。事務是用來確保數據的一致性和完整性的機制。使用 Spring 的事務管理模塊,我們可以以編程式或聲明式的方式來管理事務,從而更輕鬆地處理數據的變化和操作。spring-orm
模塊提供了與對象關係映射(ORM)框架的集成。ORM 是一種將資料庫中的數據映射到對象的技術,它使得我們可以使用面向對象的方式來操作資料庫。通過使用 Spring 的 ORM 模塊,我們可以方便地集成流行的 ORM 框架(如 Hibernate、MyBaits),並結合 Spring 的其他功能,例如簡單的聲明式事務管理。spring-oxm
模塊提供了對象和 XML 之間的映射支持。它可以幫助我們將 Java 對象轉換成 XML 格式,或者將 XML 轉換回 Java 對象。這對於處理與 XML 相關的數據非常有用。spring-jms
模塊用於處理 Java 消息服務(Java Message Service)。它提供了生成和消費消息的功能。從 Spring Framework 4.1 版本開始,它還與spring-messaging
模塊進行了集成,使得基於消息傳遞的應用程式開發更加方便。
Web
Web 層由 spring-web
、spring-webmvc
等模塊組成。
spring-web
模塊提供了基本的 Web 功能。它包含處理 MultipartFile 上傳、使用 Servlet 監聽器進行初始化 IoC 容器的功能。該模塊還包含與Web相關的部分,如 HTTP 客戶端和 Spring 遠程支持,以便與其他Web服務進行通信。spring-webmvc
模塊(也稱為Web-Servlet模塊)是 Spring 框架中用於構建 Web 應用程式的重要模塊。它實現了 Model-View-Controller(MVC)架構和 RESTful Web 服務。使用 Spring MVC,我們可以將業務邏輯代碼和 Web 表單清晰地分離,實現更好的代碼組織和可維護性。該模塊與 Spring 的其他功能無縫集成,使我們能夠輕鬆地使用依賴註入、事務管理等功能來構建靈活和可擴展的Web應用程式。
Test
spring-test
模塊支持使用 JUnit 或 TestNG 對 Spring 組件進行單元測試和集成測試,它提供了一致的 Spring ApplicationContext
載入和緩存機制,並提供了 Mock
對象,便於我們進行測試。
Spring 的歷史
Spring 框架於 2003 年誕生,是對早期 J2EE 規範複雜性的回應。雖然有些人認為 Java EE 和 Spring 存在競爭關係,但實際上,Spring 與 Java EE 相輔相成。Spring 編程模型並不包含 Java EE 平臺規範;相反,它集成了來自 EE 大傘下精心挑選的個別規範:
-
Servlet API(JSR 340)
-
WebSocket API(JSR 356)
-
Concurrency Utilities(JSR 236)
-
JSON Binding API(JSR 367)
-
Bean Validation(JSR 303)
-
JPA(JSR 338)
-
JMS (JSR914),以及必要時用於事務協調的 JTA/JCA 設置。
Spring 框架還支持依賴註入(JSR330)和常見註解(JSR250)規範,我們開發人員可以選擇使用這些規範而非由 Spring 框架提供的特定機制。
從 Spring Framework 5.0 開始,Spring 要求 Java EE 7 級別(例如 Servlet 3.1+,JPA 2.1+)作為最低要求,同時在運行時提供與 Java EE 8 級別的新API(例如 Servlet 4.0、JSON Binding API)的開箱即用集成。這使得 Spring 完全相容 Tomcat 8 和 9、WebSphere 9 以及 JBoss EAP 7 等伺服器。
隨著時間推移,在應用程式開發中 Java EE 的角色也在不斷演變。在 Java EE 和 Spring 的早期,應用程式是為部署到應用伺服器而創建的。如今,在 Spring Boot 的幫助下,應用程式以 devops 和雲友好的方式創建,Servlet 容器被嵌入其中並且易於更改。從 Spring Framework5 開始,WebFlux 應用程式甚至不直接使用 Servlet API,並且可以運行在非 Servlet 容器(例如 Netty )上。
Spring 繼續創新和發展。除了 Spring Framework 之外,還有其他項目,例如 Spring Boot、Spring Security、Spring Data、Spring Cloud、Spring Batch 等等。
Spring 設計理念
當你學習一個框架時,瞭解它所做的事情以及遵循的原則同樣重要。以下是 Spring Framework 的指導原則:
-
在每個層面提供選擇:Spring 允許我們儘可能地推遲設計決策。例如,我們可以通過配置切換應用程式所連接的資料庫而無需更改代碼。對於許多其他基礎設施問題和第三方API的集成也是如此。
-
容納不同的觀點:Spring 非常靈活,沒有固定的方式來解決應用程式的需求。它提供了多種方法來完成相同的任務,以適應不同開發者的不同觀點和需求。
-
保持強大的向後相容性:Spring Framework 的設計經過精心考慮,儘量減少對你已有代碼的影響。這意味著當我們升級到新的版本時,我們的應用程式仍然可以正常運行,而無需擔心因為框架更新而導致問題。Spring 還支持多個 Java 開發工具包(JDK)版本和第三方庫,這樣你可以繼續使用 Spring 來開發和維護你的應用程式。
-
關註 API 設計:Spring 團隊花費了大量的時間和精力來設計直觀易懂、穩定可靠的 API。他們努力確保 API 在多個版本和多年的時間跨度中保持一致性,這樣我們就可以更輕鬆地理解和使用它們。
-
確立高標準代碼質量:Spring Framework 強調清晰、準確的文檔註釋。它是少數幾個代碼結構清晰且包之間沒有迴圈依賴關係的項目之一。這種高標準的代碼質量有助於提高框架的可維護性和可擴展性。
所以什麼是 Spring?
Spring 是一個輕量級的、開源的 Java 框架,實現了 IoC(Inversion of Control)和 AOP(Aspect Oriented Programming)等功能。
在 Spring 的官網介紹中,Spring 被描述為「構建企業級應用程式的一站式框架」,它提供瞭如下的優點:
- 便於開發:Spring 的組件化和松耦合的特性使得開發變得更加簡單,開發者可以更加專註於業務邏輯的實現。
- 便於測試:Spring 的代碼結構和依賴註入機制使得測試變得更加容易。
- 便於集成:Spring 的可插拔的架構,使得其可以方便地與其他框架和組件進行集成。
- 便於部署:Spring 應用程式的部署非常簡單,開發者只需要將應用程式打成 war 包,然後將其部署到支持 Java 應用程式的伺服器上即可。
Spring 框架包含瞭如下的模塊:
- 核心容器(Core Container):包括 IoC 和 DI(Dependency Injection,依賴註入)、事件、資源、國際化、驗證、數據綁定、類型轉換、SpEL 和 AOP 等核心功能。
- AOP:支持面向切麵編程。
- 工具(Instrumentation):提供了一系列的工具和支持,如 JMS、JCA、JMX、電子郵件、任務調度和緩存等。
- 數據訪問/集成(Data Access/Integration):包括對 JDBC、ORM 框架(如 Hibernate、MyBatis)事務處理,DAO 等的支持。
- Web:包括對 Web 應用程式開發的支持,如 Spring MVC 和 Spring WebFlux 網路框架等。
- 測試(Test):包括對 JUnit、TestNG 等的支持。
沒有 Spring 和有 Spring 的區別
那到底是怎樣簡化了呢?體現在哪裡呢?下麵,為了直觀展示 Spring 是如何簡化我們開發的過程的,將寫一個代碼示例,讓大家看看是怎樣的區別。
對象管理
當沒有 Spring 時,Java EE 開發的主要方式是使用 JSP、Servlet 和 EJB 等技術。你想一想,剛開始學習 JSP 的時候,是不是這樣,沒有任何框架,純純自己操作所有東西。
對於系統中多個對象之間的關係,沒有 Spring 的時候,我們需要手動創建和管理對象之間的依賴關係。
這句話可能初學者不是很好理解,我舉個例子。
這裡有兩個設計好的系統中的兩個類,Employee 和 Department(用於描述員工以及部門信息的類)。
Employee.java:
public class Employee {
private int id;
private String name;
private Department department;
// 省略 getter 和 setter
}
Department.java:
public class Department {
private int id;
private String name;
// 省略 getter 和 setter
}
未使用 Spring 的時候
我們現在的業務假設是需要列印員工的部門信息,那麼我們就需要手動管理它們之間的依賴關係的,代碼如下:
public class Main {
public static void main(String[] args) {
Department department = new Department(1, "Just do IT");
Employee employee = new Employee(1, "god23bin", department);
System.out.println(employee.getDepartment().getName());
}
}
你創建一個 Employee 對象,就必須自己再去創建一個 Department 對象(因為 Employee 對象依賴於 Department 對象),並將 Department 對象給關聯到 Employee 對象上。是吧。現在,我相信屏幕前的你已經懂了所謂的手動創建和管理對象之間的依賴關係了。
使用 Spring 的時候
當你使用 Spring 的時候,就完全不需要這麼做。依然是這個例子,現在我使用 Spring 來操作,對象的管理就交給 Spring 處理,來看看我怎麼寫的:
@Configuration
public class AppConfig {
@Bean
public Department department() {
return new Department(1, "Just do IT");
}
@Bean
public Employee employee() {
return new Employee(1, "god23bin", department());
}
}
我寫了一個 AppConfig
類,在類上使用了一個 @Configuration
註解,表示這是一個配置類。
接著,寫了兩個方法,分別返回了一個員工對象和一個部門對象,而且在方法上使用了一個 @Bean
註解,表示這個方法返回的對象是交給 Spring IoC 進行管理的。
這兩個對象都是通過調用構造方法來創建的,其中 Department 對象則被註入到了 Employee 對象中。(註入,你就理解成 setXxx 方法)
在最上面進行介紹的時候,有一個概念,就是「容器」,這個容器人們也習慣稱「Ioc 容器」,實際上就是 Spring 用來存放與管理應用程式中所有交給它的對象的。
現在在這個容器中,就有 Department 對象和 Employee 對象。
我們的業務依舊是列印員工的部門信息,此刻,我們只需要從「容器」中獲取我們需要的對象就可以了,直接獲取員工對象,不用手動自己 new
一個員工對象,也不需要自己 new
一個部門對象了。
我們通過 AnnotationConfigApplicationContext
來載入配置類 AppConfig
,然後通過 getBean 方法來獲取 Employee 對象,此過程 Spring 完成了依賴註入的效果,Employee 對象是具有 Department 對象的。
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Employee employee = context.getBean(Employee.class);
System.out.println(employee.getDepartment().getName());
}
}
不過,實際上,我們在真正的項目中,並不會這樣去使用,即不會去手動寫 context.getBean()
等這些代碼,而是直接通過依賴註入的方式,這個後面再寫咯。現在知道是怎麼回事就 OK 啦!
當然,由於篇幅有限,可能目前你還沒能理解這樣做有什麼好處,可能會有各種疑惑,沒關係,慢慢學習下去就會迎刃而解了。
其他的管理
在沒有 Spring 時,我們需要在代碼中手動處理一些與業務邏輯無關的問題,比如連接池和事務管理等。而有了 Spring 之後,這些問題都可以通過 Spring 的 API 和組件來解決,從而使代碼更加簡潔易讀。
總結
Spring 是一個很牛的、開源的 Java 框架,實現了 IoC(Inversion of Control,控制反轉)和 AOP(Aspect Oriented Programming,面向切麵編程)等功能。
Spring 的核心特點包括便於開發、便於測試、便於集成和便於部署,啥都方便。
Spring 框架的出現簡化了 Java EE(Enterprise Edition)開發的過程。在沒有使用 Spring 的情況下,開發 Java EE 應用程式需要手動創建和管理對象之間的依賴關係,而使用 Spring 可以通過配置和註解來實現對象的自動管理和依賴註入。Spring 還提供了許多其他模塊和功能,如數據訪問/集成、Web 開發支持、AOP、工具等,使開發人員可以更加便捷地開發企業級應用程式。
總之,學習 Spring 可以幫助我們更好地理解和應用現代企業級 Java 開發的基本概念和最佳實踐,提高開發效率和代碼質量。
參考
最後的最後
希望各位屏幕前的靚仔靚女們
給個三連!你輕輕地點了個贊,那將在我的心裡世界增添一顆明亮而耀眼的星!
咱們下期再見!