1、Spring 概述
1.1、Spring 的概念和特點
Spring 是一個輕量級的控制反轉(IoC)和麵向切面(AOP)的開源容器框架,它是由 Rod Johnson(音樂學博士)所建立,其核心就是為了解決企業應用開發的複雜性。
Spring 是一款目前主流的 Java EE 輕量級開源框架,是 Java 世界最為成功的框架之一,自 2004 年 4 月,Spring 1.0 版本正式釋出以來,Spring 已經步入到了第 5 個大版本,也就是我們常說的 Spring 5。本教程使用版本為 Spring 5.3.22。
Spring 自誕生以來備受青睞,一直被廣大開發人員作為 Java 企業級應用程式開發的首選。時至今日,Spring 儼然成為了 Java EE 代名詞,成為了構建 Java EE 應用的事實標準。
Spring 框架不侷限於伺服器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何 Java 應用都可以從 Spring 中受益。Spring 框架還是一個超級粘合平臺,除了自己提供功能外,還提供粘合其他技術和框架的能力。
Spring 致力於提供一個以統一的、高效的方式構造整個應用,並且可以將單層框架以最佳的組合揉和在一起建立一個連貫的體系。例如,通過 Spring 框架,整合 MyBatis 、SpringMVC等,也就是傳說中的大雜燴。其主要具有以下特點:
-
方便解耦,簡化開發:管理所有物件的建立和依賴的關係維護。
-
AOP程式設計的支援:方便的實現對程式進行許可權攔截、執行監控等功能。
-
宣告式事務的支援:通過配置完成對事務的管理,而無需手動程式設計。
-
方便程式的測試:Spring對Junit4支援,可以通過註解方便的測試Spring程式。
-
方便整合各種優秀框架:內部提供了對各種優秀框架的直接支援。
-
降低JavaEE API的使用難度:封裝JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠端呼叫等)。
1.2、Spring 的狹義和廣義
在不同的語境中,Spring 所代表的含義是不同的。下面我們就分別從“廣義”和“狹義”兩個角度,對 Spring 進行介紹。
廣義上的 Spring 泛指以 Spring Framework 為核心的 Spring 技術棧。
經過十多年的發展,Spring 已經不再是一個單純的應用框架,而是逐漸發展成為一個由多個不同子專案(模組)組成的成熟技術,例如 Spring Framework、Spring MVC、SpringBoot、Spring Cloud、Spring Data、Spring Security 等,其中 Spring Framework 是其他子專案的基礎。
這些子專案涵蓋了從企業級應用開發到雲端計算等各方面的內容,能夠幫助開發人員解決軟體發展過程中不斷產生的各種實際問題,給開發人員帶來了更好的開發體驗,子專案主要有以下幾種:
-
Spring Data:Spring 提供的資料訪問模組,對 JDBC 和 ORM 提供了很好的支援。通過它,開發人員可以使用一種相對統一的方式,來訪問位於不同型別資料庫中的資料。
-
Spring Batch:款專門針對企業級系統中的日常批處理任務的輕量級框架,能夠幫助開發人員方便的開發出健壯、高效的批處理應用程式。
-
Spring Security:前身為 Acegi,是 Spring 中較成熟的子模組之一。它是一款可以定製化的身份驗證和訪問控制框架。
-
Spring Mobile:是對 Spring MVC 的擴充套件,用來簡化移動端 Web 應用的開發。
-
Spring Boot:是 Spring 團隊提供的全新框架,它為 Spring 以及第三方庫一些開箱即用的配置,可以簡化 Spring 應用的搭建及開發過程。
-
Spring Cloud:一款基於 Spring Boot 實現的微服務框架。它並不是某一門技術,而是一系列微服務解決方案或框架的有序集合。它將市面上成熟的、經過驗證的微服務框架整合起來,並通過 Spring Boot 的思想進行再封裝,遮蔽調其中複雜的配置和實現原理,最終為開發人員提供了一套簡單易懂、易部署和易維護的分散式系統開發工具包。
狹義的 Spring 特指 Spring Framework,通常我們將它稱為 Spring 框架。
Spring 框架是一個分層的、面向切面的 Java 應用程式的一站式輕量級解決方案,它是 Spring 技術棧的核心和基礎,是為了解決企業級應用開發的複雜性而建立的。
-
IOC:Inverse of Control 的簡寫,譯為“控制反轉”,指把建立物件過程交給 Spring 進行管理。
-
AOP:Aspect Oriented Programming 的簡寫,譯為“面向切面程式設計”。
AOP 用來封裝多個類的公共行為,將那些與業務無關,卻為業務模組所共同呼叫的邏輯封裝起來,減少系統的重複程式碼,降低模組間的耦合度。另外,AOP 還解決一些系統層面上的問題,比如日誌、事務、許可權等。
Spring 是一種基於 Bean 的程式設計技術,它深刻地改變著 Java 開發世界。Spring 使用簡單、基本的 Java Bean 來完成以前只有 EJB 才能完成的工作,使得很多複雜的程式碼變得優雅和簡潔,避免了 EJB 臃腫、低效的開發模式,極大的方便專案的後期維護、升級和擴充套件。
在實際開發中,伺服器端應用程式通常採用三層體系架構,分別為表現層(web)、業務邏輯層(service)、持久層(dao)。
Spring 致力於 Java EE 應用各層的解決方案,對每一層都提供了技術支援,例如表現成提供了對 Spring MVC、Struts2 等框架的整合;在業務邏輯層提供了管理事務和記錄日誌的功能;在持久層還可以整合 MyBatis、Hibernate 和 JdbcTemplate 等技術,對資料庫進行訪問。
這充分地體現了 Spring 是一個全面的解決方案,對於那些已經有較好解決方案的領域,Spring 絕不做重複的事情。
1.3、Spring 的體系結構
Spring 框架基本涵蓋了企業級應用開發的各個方面,它包含了 20 多個不同的模組。下圖中包含了 Spring 框架的所有模組,這些模組可以滿足一切企業級應用開發的需求,在開發過程中可以根據需求有選擇性地使用所需要的模組。下面分別對這些模組的作用進行簡單介紹。
1.3.1、Core Container(Spring 的核心容器)
Spring 的核心容器是其他模組建立的基礎,由 Beans 模組、Core 核心模組、Context 上下文模組和 SpEL 表示式語言模組組成,沒有這些核心容器,也不可能有 AOP、Web 等上層的功能。具體介紹如下。
-
spring-core模組:封裝了 Spring 框架的底層部分,包括資源訪問、型別轉換及一些常用工具類。。
-
spring-beans模組:提供了BeanFactory與Bean的裝配,使Spring成為一個容器,也就是提供了框架的基本組成部分,包括控制反轉(IOC)和依賴注入(DI)功能
-
spring-context模組:應用上下文,建立在 Core 和 Beans 模組的基礎之上,整合 Beans 模組功能並新增資源繫結、資料驗證、國際化、Java EE 支援、容器生命週期、事件傳播等,提供一個框架式的物件訪問方式,是訪問定義和配置任何物件的媒介,使Spring成為一個框架。ApplicationContext 介面是上下文模組的焦點。
-
spring-context-support模組:支援整合第三方庫到Spring應用程式上下文,特別是用於快取記憶體(EhCache、JCache)和任務排程(CommonJ、Quartz)的支援。
-
spring-expression(SpELl)模組:Spring 表示式語言全稱為“Spring Expression Language”,縮寫為“SpEL”,提供了強大的表示式語言支援,支援訪問和修改屬性值,方法呼叫,支援訪問及修改陣列、容器和索引器,命名變數,支援算數和邏輯運算,支援從 Spring 容器獲取 Bean,它也支援列表投影、選擇和一般的列表聚合等。
1.3.2、AOP、Aspects、Instrumentation 和 Messaging(中間層)
在 Core Container 之上是 AOP、Aspects 等模組,具體介紹如下:
-
spring-aop模組:提供了一個符合 AOP 要求的面向切面的程式設計實現,允許定義方法攔截器和切入點,將程式碼按照功能進行分離,以便乾淨地解耦。提供了面向切面程式設計實現,提供比如日誌記錄、許可權控制、效能統計等通用功能和業務邏輯分離的技術,並且能動態的把這些功能新增到需要的程式碼中,這樣各司其職,降低業務邏輯和通用功能的耦合。
-
spring-aspects模組:提供了與 AspectJ 的整合功能,AspectJ是 一個功能強大且成熟的面向切面程式設計(AOP) 框架。
-
spring-instrument模組:提供了類工具支援和類載入器的實現,可以在特定的應用伺服器中使用。
-
spring-messaging模組:Spring 4.0 以後新增了訊息模組,該模組提供了對訊息傳遞體系結構和協議的支援。
1.3.3、Data Access/Integration(資料訪問/整合)
資料訪問/整合層包括 JDBC、ORM、OXM、JMS 和 Transactions 模組,具體介紹如下。
-
spring-jdbc模組:提供了一個 JBDC 的樣例模板,,使用這些模板能消除傳統冗長的 JDBC 編碼還有必須的事務控制,消除了煩瑣的JDBC編碼和資料庫廠商特有的錯誤程式碼解析,而且能享受到 Spring 管理事務的好處。
-
spring-orm模組:提供一個物件關係對映(Object-Relational Mapping)API 框架,包括 JPA、JDO、Hibernate 和 MyBatis 等。而且還可以使用 Spring 事務管理,無需額外控制事務。
-
spring-oxm模組:提供了一個支援 Object /XML 對映的抽象層實現,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。將 Java 物件對映成 XML 資料,或者將XML 資料對映成 Java 物件。
-
spring-jms模組:指 Java 訊息服務,提供一套 “訊息生產者、訊息消費者”模板用於更加簡單的使用 JMS,JMS 用於用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。
-
spring-tx模組:事務模組,支援用於實現特殊介面和所有POJO類的程式設計和宣告式事務管理。
1.3.4、Web 模組
Spring 的 Web 層包括 Web、Servlet、WebSocket 和 Portlet 元件,具體介紹如下。
-
spring-web模組:提供了基本的 Web 開發整合特性,例如多檔案上傳功能、使用的 Servlet 監聽器的 IOC 容器初始化以及 Web 應用上下文。
-
spring-webmvc模組:提供了一個 Spring MVC Web 框架實現。Spring MVC 框架提供了基於註解的請求資源注入、更簡單的資料繫結、資料驗證等及一套非常易用的 JSP 標籤,完全無縫與 Spring 其他技術協作。
-
spring-websocket模組:提供了簡單的介面,使用者只要實現響應的介面就可以快速的搭建 WebSocket Server,從而實現雙向通訊。
-
spring-portlet模組:提供了在 Portlet 環境中使用 MVC 實現,類似 Web-Servlet 模組的功能。
1.4 Spring Hello World
首先我們需要建立一個 Maven 專案,建立成功後,我們需要匯入 Spring 的相關依賴,這裡推薦直接匯入 spring-webmvc,這個 jar 包預設會為我們匯入其他的依賴包,匯入如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>JavaEE</artifactId>
<groupId>com.loner</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Spring</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
</dependencies>
</project>
依賴匯入成功後,等待 Maven 拉取即可,接下來我們需要建立一個 HelloWorld 實體類,此類只有一個字串了型別的欄位,生成其 getter 和 setter 以及 toString()方法即可,實體類實現如下:
public class HelloWorld {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "HelloWorld{" + "message='" + message + '\'' + '}';
}
}
實體類建立成功後,我們就需要使用 Spring 的特有方式來裝配 Bean,這也是 Spring 的核心思想,將物件的建立和銷燬完全交付給 Spring 進行管理,我們只需要進行簡單的配置即可使用。首先我們需要在 resource 目錄下建立一個 Spring 的 xml 配置檔案,名稱隨意,推薦使用 applicationContext.xml。建立成功後,需要引入 Spring 各個模組的約束,然後通過 <bean></bean>
進行 Bean 的裝配,具體實現如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 裝配Bean,相當於new一個HelloWorld物件,id等同於變數名,class就是類路徑 -->
<bean id="helloWorld" class="com.loner.mj.pojo.HelloWorld">
<!-- 設定屬性及其對應的值,name為實體的屬性名,value為屬性的值 -->
<property name="message" value="第一個Spring程式" />
</bean>
</beans>
注意,這裡的 Bean 裝配是通過 xml 配置檔案的方式實現的,還有註解的實現方式。
Bean 裝配後,我們需要通過 Spring 的入口進行應用的啟動,此時我們需要例項化 ClassPathXmlApplicationContext 物件,此物件需要傳入一個或多個 xml 配置檔案,他是 ApplicationContext 介面的一個實現類,此介面的實現類有很多,這裡我們只使用 ClassPathXmlApplicationContext 物件,實現方式如下:
public class HelloTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// getBean的屬性值就是Bean標籤的id值
HelloWorld bean = (HelloWorld) applicationContext.getBean("helloWorld");
System.out.println(bean.getMessage());
}
}
到此為止,整個 Spring 應用即編寫完成,啟動程式後,控制檯輸出“第一個Spring程式”。從以上程式可以看出,我們從未手動的例項化過物件,我們只是在 Spring 的配置檔案中,進行了 Bean 的裝配,然後就可以在程式中使用此 Bean,這也印證了,Spring 框架無需我們考慮和關心 Bean 在何時例項化,我們只需要關心自己的核心業務即可,所有的 Bean 的建立和銷燬都是 Spring 框架幫我們完成。