一、為何以繼承方式引入SpringBoot
1.提出疑問
以前我們在開發項目時,需要什么,引入對應的依賴就行,比如我們需要連接mysql數據,則引入mysql驅動的依賴,如下:
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version>
</dependency>
現在我們要使用SpringBoot框架,按說也應該采用依賴的方式將SpringBoot框架引入,如下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version>
</dependency>
但是SpringBoot官方推薦的不是直接引入依賴,而是采用繼承的方式實現,如下:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version>
</parent>
為什么
2.作為父項目和作為依賴的區別
繼承父工程的優勢
-
依賴管理:可以在父工程中定義依賴的版本,子模塊可以直接引用而不必指定版本號。
-
插件管理:可以在父工程中配置常用的插件及其版本,子模塊可以直接使用這些配置。
-
屬性設置:可以在父工程中定義一些通用的屬性,如項目編碼、Java 版本等。
-
統一配置:可以統一多個子模塊的構建配置,確保一致性。
直接引入依賴的局限性(如果你不使用繼承父工程的方式,而是通過直接引入依賴的方式來管理項目,那么你將失去上述的一些優勢)
-
依賴版本管理:每個子模塊都需要單獨指定依賴的版本,這會導致大量的重復配置,并且難以維護。
-
插件配置:每個子模塊都需要單獨配置插件及其版本,無法共享父工程中的插件配置。
-
屬性設置:每個子模塊都需要單獨設置通用的屬性,如項目編碼、Java 版本等。
-
構建配置:每個子模塊的構建配置需要單獨維護,難以保證一致性。
總結:選擇哪種方式取決于你的具體需求。
-
如果你希望多個項目之間共享構建配置,那么使用父項目是一個好的選擇;
-
如果你只是想在項目之間共享代碼,那么應該使用依賴關系。
3.原理揭曉
通過源碼來分析一下:
通過上圖源碼可以看到Spring Boot預先對開發中需要用到的依賴進行了版本的統一管理。我們需要和SpringBoot框架共享這個構建配置。因此官方推薦使用繼承的方式引入SpringBoot框架。
3.依賴統一管理的好處
Spring Boot 框架的一個重要特性就是簡化了項目依賴管理。它通過提供一個叫做“依賴管理”的功能來幫助開發者更容易地管理和使用第三方庫和其他 Spring 組件。具體來說,Spring Boot 提供了一個包含多個 Spring 和其他常用庫的依賴版本配置文件(通常是在 spring-boot-dependencies
文件中),這使得開發者不需要在自己的項目中顯式指定這些依賴的版本號。
這樣做有以下幾個好處:
-
簡化依賴聲明: 開發者只需要在
pom.xml
文件中聲明需要的依賴而不需要指定其版本號,因為 Spring Boot 已經為這些依賴指定了版本。例如,如果你需要使用mysql驅動,你只需要添加相應的依賴聲明而不需要關心版本。
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId>
</dependency>
-
避免版本沖突: 當多個庫之間存在依賴關系的時候,如果手動管理版本可能會導致版本之間的沖突(即“依賴地獄”)。Spring Boot 提供的統一版本管理可以減少這種沖突的可能性。
-
易于升級: 當 Spring Boot 發布新版本時,通常會更新其依賴庫到最新穩定版。因此,當你升級 Spring Boot 版本時,它所管理的所有依賴也會隨之更新到兼容的版本。
-
減少配置錯誤: 由于 Spring Boot 自動處理了依賴的版本,減少了手動輸入版本號可能引入的拼寫或格式錯誤。
-
提高開發效率: 開發者可以專注于業務邏輯的編寫,而不是花費時間在解決依賴問題上。
總的來說,Spring Boot 的依賴管理功能使得開發者可以更加專注于業務邏輯的實現,同時減少了因依賴版本不一致而引發的問題,提高了項目的可維護性和開發效率。
當然,如果你在項目中需要更改某個依賴的版本號,不想使用SpringBoot框架指定的版本號,只需要在引入依賴時強行執行版本號即可,maven是支持就近原則的:
這樣做就是采用SpringBoot指定版本的依賴:
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId>
</dependency>
這樣做就是不采用SpringBoot指定版本的依賴:
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.2.0</version>
</dependency>
二、Starter-啟動器
在 Spring Boot 中,啟動器(Starter)本質上是一個簡化依賴管理的概念。
Spring Boot 的啟動器本質上就是一組預定義的依賴集合,它們被組織成一個個 Maven的依賴,以方便開發者快速集成特定的功能模塊。
如果你想做web開發,只需要引入web啟動器。web啟動器會自動引入web開發所需要的子依賴。
1.啟動器實現原理
依賴聚合: 每個啟動器通常對應一個特定的功能集或者一個完整的應用模塊,如
spring-boot-starter-web
就包含了構建 Web 應用所需的所有基本依賴項,如 Spring MVC, Tomcat 嵌入式容器等。依賴傳遞: 當你在項目中引入一個啟動器時,它不僅會把自身作為依賴加入到你的項目中,還會把它的所有直接依賴項(transitive dependencies)也加入進來。這意味著你不需要單獨聲明這些依賴項,它們會自動成為項目的一部分。
版本管理: 啟動器內部已經指定了所有依賴項的具體版本,這些版本信息存儲在一個公共的 BOM(Bill of Materials,物料清單)文件中,通常是
spring-boot-dependencies
。當引入啟動器時,實際上也間接引用了這個 BOM,從而確保了所有依賴項版本的一致性。自動配置: 許多啟動器還提供了自動配置(Auto-configuration),這是一種機制,允許 Spring Boot 根據類路徑上的可用組件自動設置你的應用程序。例如,如果類路徑上有 Spring MVC 和嵌入式 Tomcat,則 Spring Boot 會自動配置它們,并準備好一個 web 應用程序。
使用啟動器的示例
假設你想創建一個基于 Spring MVC 的 RESTful Web 應用,你可以簡單地將 spring-boot-starter-web
添加到你的項目中:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
當你添加這個依賴時,Spring Boot 會處理所有必要的細節,包括添加 Spring MVC 和 Tomcat 作為嵌入式 Servlet 容器,并且根據類路徑上的內容進行適當的自動配置。如下圖所示:
這就是 Spring Boot 啟動器的基本實現原理,它簡化了依賴管理,讓開發者能夠更專注于業務邏輯的實現。
2.都有哪些啟動器
啟動器通常包括:
-
SpringBoot官方提供的啟動器
-
非官方提供的啟動器
官方提供的啟動器
啟動器命名特點:spring-boot-starter-*
非官方的啟動器
啟動器命名特點:*-spring-boot-starter
三、Spring Boot核心注解
創建一個新的模塊,來學習Spring Boot核心注解:
1.@SpringBootApplication注解
Spring Boot的主入口程序被@SpringBootApplication
注解標注,可見這個注解的重要性,查看它的源碼:
可以看出這個注解屬于組合注解
。擁有@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
的功能。
2.@SpringBootConfiguration注解
@SpringBootConfiguration注解的源碼如下:
可以看到這個注解的被@Configuration
標注,說明主入口
程序是一個配置類。也就是說主入口中的方法可以被@Bean
注解標注,被@Bean
注解的標注的方法會被Spring容器自動調用,并且將該方法的返回對象納入IoC容器的管理。
SpringBoot主入口類實際上就是一個配置類
。
這個配置類
也可以稱為源
,起源的意思,SpringBoot從這個配置類開始加載項目中所有的bean。
3.@EnableAutoConfiguration注解
該注解表示`啟用自動配置`。
Spring Boot 會根據你引入的依賴自動為你配置好一系列的 Bean,無需手動編寫復雜的配置代碼。
例如:如果你在SpringBoot項目中進行了如下配置:
關于 @EnableAutoConfiguration 注解:啟用自動配置。也就是說默認情況下,springboot應用都會默認啟用自動配置。自動配置有什么用?所謂的自動配置只要啟動,springboot應用會去類路徑當中查找class,根據類路徑當中有某個類,或某些類,來自動管理bean,不需要我們程序員手動配置。比如:springboot檢測到類路徑當中有 SqlSessionFactory,或者在application.properties文件中配置了數據源,那么springboot會認為項目中有mybatis框架,因此會將mybatis中相關的bean自動初始化,然后放到IoC容器當中,自動將這些bean管理起來。sqlSessionFactorytransactionManager
并且在依賴中引入了mybatis依賴
/mybatis啟動器
,那么SpringBoot框架將為你自動化配置以下bean:
-
SqlSessionFactory: MyBatis的核心工廠SqlSessionFactory會被自動配置。這個工廠負責創建SqlSession實例,后者用來執行映射文件中的SQL語句。
-
TransactionManager: DataSourceTransactionManager會被自動配置來管理與數據源相關的事務。
4.@ComponentScan注解
這個注解的作用是:啟動組件掃描功能,代替spring框架xml文件中這個配置:
<context:component-scan base-package="com.powernode.sb305core"/>
因此被`@SpringBootApplication`注解標注之后,會啟動組件掃描功能,掃描的包是`主入口程序所在包及子包`,因此如果一個bean要納入IoC容器的管理則必須放到主入口程序所在包及子包下。放到主入口程序所在包之外的話,掃描不到。測試一下:
結論:要讓bean納入IoC容器的管理,必須將類放到主入口程序同級目錄下,或者子目錄下。
四、Spring Boot的單元測試
1.不使用單元測試怎么調用service
User
package org.example1.springboot03.bean;public class User {private String username;private String password;@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}public User(String username, String password) {this.username = username;this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
service:
入口:
測試:
2.使用單元測試怎么調用service
⑴.test-starter引入以及測試類編寫
使用單元測試應該如何調用service對象上的方法呢?
在使用腳手架創建Spring Boot項目時,為我們生成了單元測試類,如下:
要使用單元測試,需要引入單元測試啟動器,如果使用腳手架創建SpringBoot項目,這個test啟動器會自動引入:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
⑵.@SpringBootTest注解
@SpringBootTest
會創建一個完整的 Spring 應用程序上下文(Application Context),這個上下文包含了應用程序的所有組件和服務。以下是 @SpringBootTest
做的一些主要工作:
-
創建 ApplicationContext:
-
@SpringBootTest
使用SpringApplication
的run()
方法來啟動一個 Spring Boot 應用程序上下文。這意味著它會加載應用程序的主配置類和其他相關的配置類。
-
-
加載配置文件:
-
它會查找并加載默認的配置文件,如
application.properties
-
-
自動配置:
-
如果應用程序依賴于 Spring Boot 的自動配置特性,
@SpringBootTest
會確保這些自動配置生效。這意味著它會根據可用的類和bean來自動配置一些組件,如數據庫連接、消息隊列等。
-
-
注入依賴:
-
使用
@SpringBootTest
創建的應用程序上下文允許你在測試類中使用@Autowired
注入需要的 bean,就像在一個真實的 Spring Boot 應用程序中一樣。
-
總的來說,@SpringBootTest
為你的測試提供了盡可能接近實際運行時環境的條件,這對于驗證應用程序的行為非常有用。
測試結果如下:
五、外部化配置
1.什么是外部化配置
外部化配置是指:將配置信息
存儲在應用程序代碼
之外的地方。這樣配置信息
可以獨立于代碼進行管理。這樣方便了配置的修改,并且修改后不需要重新編譯代碼,也不需要重新部署項目。
⑴.外部化配置的方式
SpringBoot支持多種外部化配置方式,包括但不限于:
properties文件
YAML文件
系統環境變量
命令行參數
......
⑵.外部化配置的優勢
-
靈活性:配置文件可以獨立于應用程序部署,這使得可以根據運行環境的不同來調整配置,而無需修改代碼。
-
易于維護:配置變更不需要重新構建和部署應用程序,降低了維護成本。
-
安全性:敏感信息如數據庫密碼、API密鑰等可以存儲在外部,并且可以限制誰有權限訪問這些配置信息。
-
共享性:多實例或多服務可以共享相同的配置信息,減少重復配置的工作量。
-
版本控制:配置文件可以存放在版本控制系統中,便于跟蹤歷史版本和回滾配置。
總之,外部化配置使得配置更加靈活、安全、易于管理和共享,是現代云原生應用中非常推薦的做法
⑶.外部化配置對比傳統配置
在傳統的SSM三大框架中,如果修改XML的配置后,需要對應用重新打包,重新部署。
使用SpringBoot框架的外部化配置
后,修改配置后,不需要對應用重新打包,也不需要重新部署,最多重啟一下服務即可。
2.application.properties
application.properties
配置文件是SpringBoot框架默認的配置文件。
application.properties
不是必須的,SpringBoot對于應用程序來說,都提供了一套默認配置(就是我們所說的自動配置)。
如果你要改變這些默認的行為,可以在application.properties
文件中進行配置。
application.properties
可以放在類路徑當中,也可以放在項目之外。因此稱為外部化配置。
Spring Boot 框架在啟動時會嘗試從以下位置加載 application.properties
配置文件:
Spring Boot 加載application.properties或application.yml配置文件的位置順序。
Spring Boot 會按照這個順序來加載配置文件,如果在多個位置有相同的屬性定義,那么最先檢查的位置中的屬性值將優先使用。
如果你想要指定其他的配置文件位置或者改變默認的行為,可以通過 --spring.config.location=
后跟路徑的方式來指定配置文件的具體位置。例如 :
java -jar sb3-01-first-web-1.0-SNAPSHOT.jar
--spring.config.location=file:///E:\a\b\application.properties
這樣,Spring Boot 將會首先從 E:\a\b\
這個路徑加載配置文件。注意,這種方式可以用來覆蓋默認的配置文件位置,并且可以結合以上提到的位置一起使用。
注意:以上的--spring.config.location=file:///E:\a\b\application.properties
就屬于命令行參數,它將來會被傳遞到main方法的(String[] args)參數上。
3.使用@Value注解
@Value注解可以將application.properties
/application.yml
文件中的配置信息注入/綁定到java對象的屬性上。
語法格式:@Value("${key}")
使用腳手架創建SpringBoot項目,不添加任何啟動器:
使用@Value注解時也可以指定默認值,當指定默認值時,如果配置文件中沒有指定配置值,則采用默認值。
語法格式:@Value("${key:defalut}")
@Service("userService")
public class UserService {@Value("${myapp.username}")private String username;@Value("${myapp.email}")private String email;@Value("${myapp.age}")private Integer age;@Value("${myapp.password:123456}")private String password;public void printInfo(){String str = String.join(",", username, email, String.valueOf(age), password);System.out.println(str);}
}
4.YAML
YAML概述
SpringBoot采用集中式配置管理,所有的配置都編寫到一個配置文件中:application.properties
如果配置非常多,層級不夠分明,因此SpringBoot為了提高配置文件可讀性,也支持YAML格式的配置文件:application.yml
YAML(YAML Ain't Markup Language)是一種人類可讀的數據序列化格式,它通常用于配置文件,在各種編程語言中作為一種存儲或傳輸數據的方式。YAML的設計目標是易于閱讀和編寫,同時保持足夠的表達能力來表示復雜的數據結構。
YAML文件的擴展名可以是.yaml
或.yml
常見的數據存儲和交換格式
properties
、XML
、JSON
、YAML
這幾種格式確實是用來存儲和交換數據的常見方式,但它們各有特點和適用場景:
Properties
-
這種格式主要用于Java應用程序中的配置文件。它是鍵值對的形式,每一行是一個鍵值對,使用等號或冒號分隔鍵和值。
-
特點是簡單易懂,但在處理復雜結構的數據時顯得力不從心。
XML (eXtensible Markup Language)
-
XML是一種標記語言,用來描述數據的格式。它支持復雜的數據結構,包括嵌套和屬性。
-
XML文檔具有良好的結構化特性,適合傳輸和存儲結構化的數據。但是,XML文檔通常體積較大,解析起來也比較耗資源。
JSON (JavaScript Object Notation)
-
JSON是一種輕量級的數據交換格式,易于人閱讀和編寫,同時也易于機器解析和生成。它基于JavaScript的一個子集,支持多種數據類型,如數字、字符串、布爾值、數組和對象。
-
JSON因為簡潔和高效而廣泛應用于Web應用程序之間進行數據交換。
YAML (YAML Ain't Markup Language)
-
YAML設計的目標之一就是讓人類更容易閱讀。它支持類似JSON的數據序列化,但提供了更多的靈活性,例如縮進來表示數據結構。
-
YAML非常適合用來編寫配置文件,因為它允許以一種自然的方式組織數據,并且可以包含注釋和其他人類可讀的元素。
總結來說,這四種格式都可以用來存儲和交換數據,但它們的設計初衷和最佳使用場景有所不同。選擇哪種格式取決于具體的應用需求、數據復雜度、性能要求等因素。
YAML的語法規則
YAML的語法規則如下:
-
數據結構:YAML支持多種數據類型,包括:
-
字符串、數字、布爾值
-
數組、list集合
-
map鍵值對 等。
-
-
YAML使用
一個空格
來分隔屬性名
和屬性值
,例如:-
properties
文件中這樣的配置:name=jack -
yaml
文件中需要這樣配置:name: jack
-
-
YAML用
換行+空格
來表示層級關系。注意不能使用tab,必須是空格,空格數量無要求,大部分建議2個或4個空格。例如:-
properties
文件中這樣的配置:myapp.name=mall -
yaml
文件中就需要這樣配置:
-
myapp:name: mall
4.同級元素左對齊。
? ? ? ? ?1.例如: properties文件中有這樣的配置:
myapp.name=mall
myapp.count=10
? ? ? ? ? 2. `yaml`文件中就應該這樣配置:
myapp:name: mallcount: 10
5.鍵必須是唯一的:在一個映射中,鍵必須是唯一的。
6.注釋:使用#進行注釋。
7.大小寫敏感
YAML的使用小細節
第一:普通文本也可以使用單引號或雙引號括起來:(當然普通文本也可以不使用單引號和雙引號括起來。)
-
單引號括起來:單引號內所有的內容都被當做普通文本,不轉義(例如字符串中有\n,則\n被當做普通的字符串)
-
雙引號括起來:雙引號中有 \n 則會被轉義為換行符
第二:保留文本格式
-
| 將文本寫到這個符號的下層,會自動保留格式。
第三:文檔切割
-
--- 這個符號下面的配置可以認為是一個獨立的yaml文件。便于龐大文件的閱讀。
# 普通文本引號使用示例
# 不使用引號
plainTextNoQuotes: 這是一段普通文本
# 使用單引號
plainTextSingleQuotes: '這是一段包含 \n 的普通文本,\n 不會被轉義'
# 使用雙引號
plainTextDoubleQuotes: "這是一段包含 \n 的普通文本,\n 會被轉義為換行符"# 保留文本格式示例
preserveFormat: |這是一段保留格式的文本。它會按照這里的格式進行顯示。每行內容都會保持原有的換行。# 文檔切割示例
---
# 這部分配置可以認為是一個獨立的yaml文件
newDocument:key1: value1key2: value2
---
# 又一個獨立的配置文檔
anotherDocument:item1: 123item2: 456
application.yml
Spring Boot框架同時支持properties
和yaml
。
在 Spring Boot 里,當同一個目錄下同時存在application.properties
和application.yml
文件時,application.properties
文件會被優先解析。
在resources/config
目錄下新建application.yml
文件,進行如下配置:
5.配置文件合并
一個項目中所有的配置全部編寫到application.properties
文件中,會導致配置臃腫,不易維護,有時我們會將配置編寫到不同的文件中,例如:
application-mysql.properties
專門配置mysql的信息,
application-redis.properties
專門配置redis的信息,最終將兩個配置文件合并到一個配置文件中。
properties文件
創建配置文件
在src/main/resources
目錄下創建以下三個配置文件:
application.properties
spring.config.import=application-mysql.properties,application-redis.properties
這里使用spring.config.import
屬性來引入其他配置文件,多個文件之間用逗號分隔。
application-mysql.properties
mysql.host=localhost
mysql.port=3306
mysql.username=root
mysql.password=password
此文件用于配置 MySQL 相關信息。
application-redis.properties
redis.host=localhost
redis.port=6379
redis.password=redis_password
這個文件用于配置 Redis 相關信息。
yaml文件
application-mysql.yml
spring:datasource:username: rootpassword: 789789
application-redis.yml
spring:data:redis:host: localhostport: 6379
application.yml
spring:config:import:- classpath:application-mysql.yml- classpath:application-redis.yml
6.多環境切換
在Spring Boot中,多環境切換是指在一個應用程序中支持多種運行環境配置的能力。這通常用于區分開發(development)、測試(testing)、預生產(staging)和生產(production)等不同階段的環境。
這種功能使得開發者能夠在不同的環境中使用不同的配置,比如數據庫連接信息、服務器端口、環境變量等,而不需要更改代碼。這對于維護一個可移植且易于管理的應用程序非常重要。
開發環境的配置文件名一般叫做:application-dev.properties
spring.datasource.username=dev
spring.datasource.password=dev123
spring.datasource.url=jdbc:mysql://localhost:3306/dev
測試環境的配置文件名一般叫做:application-test.properties
spring.datasource.username=test
spring.datasource.password=test123
spring.datasource.url=jdbc:mysql://localhost:3306/test
預生產環境的配置文件名一般叫做:application-preprod.properties
spring.datasource.username=preprod
spring.datasource.password=preprod123
spring.datasource.url=jdbc:mysql://localhost:3306/preprod
生產環境的配置文件名一般叫做:application-prod.properties
spring.datasource.username=prod
spring.datasource.password=prod123
spring.datasource.url=jdbc:mysql://localhost:3306/prod
如果你希望該項目使用生產環境的配置,你可以這樣做:
第一種方式:在?application.properties
?文件中添加配置
在?application.properties
?文件里添加以下內容:
spring.profiles.active=prod
第二種方式:在命令行參數上添加配置
假設你運用的是 Java 程序,以下是啟動時添加命令行參數的示例:
java -jar your-application.jar --spring.profiles.active=prod
若你使用的是 Maven 來運行項目,示例如下:
mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=prod
要是你運用的是 Gradle 來運行項目,示例如下:
gradle bootRun --args='--spring.profiles.active=prod'
7.將配置綁定到bean
綁定簡單bean
SpringBoot配置文件中的信息除了可以使用@Value注解
讀取之外,也可以將配置信息一次性賦值給Bean對象的屬性。
例如有這樣的配置:
Bean需要這樣定義:
說明:
1.被綁定的bean,需要使用@ConfigurationProperties(prefix = "app")
注解進行標注,prefix用來指定前綴
bean中的所有屬性都提供了setter
方法。因為底層是通過setter
方法給bean屬性賦值的。
2.這樣的bean需要使用@Component
注解進行標注,納入IoC容器的管理。@Component
注解負責創建Bean對象,@ConfigurationProperties(prefix = "app")
注解負責給bean對象的屬性賦值。
3.bean的屬性需要是非static
的屬性。
編寫測試程序,將bean對象輸出,結果如下:
@Configuration注解
以上操作中使用了@Component注解
進行了標注,來納入IoC容器的管理。也可以使用另外一個注解@Configuration
,用這個注解將Bean標注為配置類。多數情況下我們會選擇使用這個注解,因為該Bean對象的屬性對應的就是配置文件中的配置信息,因此這個Bean我們也可以將其看做是一個配置類。
綁定嵌套bean
當一個Bean中嵌套了一個Bean,這種情況下可以將配置信息綁定到該Bean上嗎?當然可以。
有這樣的一個配置:
需要編寫這樣的兩個Bean:
執行測試程序,結果如下:
@EnableConfigurationProperties與@ConfigurationPropertiesScan
將AppBean
納入IoC容器的管理,之前我們說了兩種方式:第一種是使用@Component
,第二種是使用@Configuration
。SpringBoot其實還提供了另外兩種方式:
-
第一種:@EnableConfigurationProperties
-
第二種:@ConfigurationPropertiesScan
這兩個注解都是標注在SpringBoot主入口程序上的:
運行測試:
將配置賦值到Bean的Map/List/Array屬性上
代碼如下:
package org.example1.springboot310configbindtobean.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.Arrays;
import java.util.List;
import java.util.Map;@ConfigurationProperties(prefix = "app2.abc")
public class AppBean {// 數組:數組中元素是簡單類型private String[] names;// 數組:數組中元素是beanprivate Address[] addrArray;// List集合:集合中的元素是beanprivate List<Address> addrList;// Map集合:String,Beanprivate Map<String, Address> addrs;public void setNames(String[] names) {this.names = names;}public void setAddrArray(Address[] addrArray) {this.addrArray = addrArray;}public void setAddrList(List<Address> addrList) {this.addrList = addrList;}public void setAddrs(Map<String, Address> addrs) {this.addrs = addrs;}@Overridepublic String toString() {return "AppBean{" +"names=" + Arrays.toString(names) +", addrArray=" + Arrays.toString(addrArray) +", addrList=" + addrList +", addrs=" + addrs +'}';}
}
配置信息如下:
測試:
補充yml的寫法:
將配置綁定到第三方對象
將配置文件中的信息綁定到某個Bean對象上,如果這個Bean對象沒有源碼,是第三方庫提供的,怎么辦?
此時可以單獨編寫一個方法,在方法上使用以下兩個注解進行標注:
-
@Bean
-
@ConfigurationProperties
假設我們有這樣一個類Address(假設這個Address是第三方寫的,我們無權修改)
,代碼如下:
實現代碼如下:
測試代碼:
指定數據來源
指定數據的來源用的
之前所講的內容是將Spring Boot框架默認的配置文件application.properties
或application.yml
作為數據的來源綁定到Bean上。如果配置信息沒有在默認的配置文件中呢?可以使用@PropertySource注解指定配置文件的位置,這個配置文件可以是.properties
,也可以是.xml
。這里重點掌握.properties
即可。
在resources
目錄下新建a
目錄,在a
目錄下新建b
目錄,b
目錄中新建group-info.properties
文件,進行如下的配置:
定義Java類`Group`,然后進行注解標注:
以下三個注解分別起到什么作用:
-
@Configuration:指定該類為配置類,納入Spring容器的管理
-
@ConfigurationProperties(prefix = "group"):將配置文件中的值賦值給Bean對象的屬性
-
@PropertySource("classpath:a/b/group-info.properties"):指定額外的配置文件
編寫測試程序,測試結果如下:
8.@ImportResource注解
創建Bean的三種方式總結:
-
第一種方式:編寫applicationContext.xml文件,在該文件中注冊Bean,Spring容器啟動時實例化配置文件中的Bean對象。
-
第二種方式:@Configuration注解結合@Bean注解。
-
第三種方式:@Component、@Service、@Controller、@Repository等注解。
第二種和第三種我們都已經知道了。針對第一種方式,如果在SpringBoot框架中應該怎么實現呢?使用@ImportResource注解實現
定義一個普通的Java類:Person
package org.example1.springboot310configbindtobean.bean;public class Person {private String name;private int age;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
在resources
目錄下新建applicationContext.xml
配置文件:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="person" class="org.example1.springboot310configbindtobean.bean.Person"><property name="name" value="jackson"/><property name="age" value="20"/></bean></beans>
在SpringBoot主入口類上添加@ImportResource進行資源導入,這樣applicationContext.xml
文件中的Bean將會納入IoC容器的管理:
編寫測試程序,看看是否可以獲取到person
這個bean對象:
因此,項目中如果有類似于Spring的這種xml配置文件,要想納入IoC容器管理,需要在入口類上使用@ImportResource("classpath:applicationContext.xml")
注解即可。
9.Environment
SpringBoot框架在啟動的時候會將系統配置,環境信息全部封裝到Environment
對象中,如果要獲取這些環境信息,可以調用Environment
接口的方法。
在Spring Boot中,Environment
接口提供了訪問應用程序環境信息的方法,比如活動配置文件、系統環境變量、命令行參數等。Environment
接口由Spring框架提供,Spring Boot應用程序通常會使用Spring提供的實現類AbstractEnvironment
及其子類來實現具體的環境功能。
Environment
對象封裝的主要數據包括:
Active Profiles: 當前激活的配置文件列表。Spring Boot允許應用程序定義不同的環境配置文件(如開發環境、測試環境和生產環境),通過激活不同的配置文件來改變應用程序的行為。
System Properties: 系統屬性,通常是操作系統級別的屬性,比如操作系統名稱、Java版本等。
System Environment Variables: 系統環境變量,這些變量通常是由操作系統提供的,可以在啟動應用程序時設置特定的值。
Command Line Arguments: 應用程序啟動時傳遞給主方法的命令行參數。
Property Sources:
Environment
還包含了一個PropertySource
列表,這個列表包含了從不同來源加載的所有屬性。PropertySource
可以來自多種地方,比如配置文件、系統屬性、環境變量等。
在Spring Boot中,可以通過注入Environment
來獲取上述信息。例如:
通過這種方式,你可以根據環境的不同靈活地配置你的應用程序。Environment
是一個非常有用的工具,它可以幫助你管理各種類型的配置信息,并根據不同的運行時條件做出相應的調整。
六、Spring Boot中如何進行AOP的開發
1.Spring Boot AOP概述
面向切面編程AOP在Spring教程中已經進行了詳細講解,這里不再贅述,如果忘記的同學,可以重新聽一下Spring教程中AOP相關的內容。這里僅帶著大家在Spring Boot中實現AOP編程。
Spring Boot的AOP編程和Spring框架中AOP編程的唯一區別是:引入依賴的方式不同。其他內容完全一樣。Spring Boot中AOP編程需要引入aop啟動器:
<!--aop啟動器-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
可以看到,當引入aop啟動器
之后,會引入aop依賴
和aspectj依賴
。
-
aop依賴:如果只有這一個依賴,也可以實現AOP編程,這種方式表示使用了純Spring AOP實現aop編程。
-
aspectj依賴:一個獨立的可以完成AOP編程的AOP框架,屬于第三方的,不屬于Spring框架。(我們通常用它,因為它的功能更加強大)
2.Spring Boot AOP實現
實現功能:項目中很多service,要求執行任何service中的任何方法之前
記錄日志。
創建Spring Boot項目引入aop啟動器
<!--aop啟動器-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
編寫service并提供方法
package org.example1.springboot311aop.service;public interface UserService {/*** 保存用戶信息* @param id 用戶id* @param name 用戶名*/void save(Long id, String name);/*** 根據id刪除用戶* @param id 用戶id*/void deleteById(Long id);
}
package org.example1.springboot311aop.service.impl;import org.example1.springboot311aop.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Overridepublic void save(Long id, String name) {System.out.println("正在保存用戶信息:" + name);}@Overridepublic void deleteById(Long id) {System.out.println("正在刪除用戶" + id + "信息");}
}
編寫切面
測試