第2章——springboot核心機制


一、為何以繼承方式引入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.啟動器實現原理

  1. 依賴聚合: 每個啟動器通常對應一個特定的功能集或者一個完整的應用模塊,如 spring-boot-starter-web 就包含了構建 Web 應用所需的所有基本依賴項,如 Spring MVC, Tomcat 嵌入式容器等。

  2. 依賴傳遞: 當你在項目中引入一個啟動器時,它不僅會把自身作為依賴加入到你的項目中,還會把它的所有直接依賴項(transitive dependencies)也加入進來。這意味著你不需要單獨聲明這些依賴項,它們會自動成為項目的一部分。

  3. 版本管理: 啟動器內部已經指定了所有依賴項的具體版本,這些版本信息存儲在一個公共的 BOM(Bill of Materials,物料清單)文件中,通常是 spring-boot-dependencies。當引入啟動器時,實際上也間接引用了這個 BOM,從而確保了所有依賴項版本的一致性。

  4. 自動配置: 許多啟動器還提供了自動配置(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 做的一些主要工作:

  1. 創建 ApplicationContext

    • @SpringBootTest 使用 SpringApplicationrun() 方法來啟動一個 Spring Boot 應用程序上下文。這意味著它會加載應用程序的主配置類和其他相關的配置類。

  2. 加載配置文件

    • 它會查找并加載默認的配置文件,如 application.properties

  3. 自動配置

    • 如果應用程序依賴于 Spring Boot 的自動配置特性,@SpringBootTest 會確保這些自動配置生效。這意味著它會根據可用的類和bean來自動配置一些組件,如數據庫連接、消息隊列等。

  4. 注入依賴

    • 使用 @SpringBootTest 創建的應用程序上下文允許你在測試類中使用 @Autowired 注入需要的 bean,就像在一個真實的 Spring Boot 應用程序中一樣。

總的來說,@SpringBootTest 為你的測試提供了盡可能接近實際運行時環境的條件,這對于驗證應用程序的行為非常有用。

測試結果如下:

五、外部化配置

1.什么是外部化配置

外部化配置是指:將配置信息存儲在應用程序代碼之外的地方。這樣配置信息可以獨立于代碼進行管理。這樣方便了配置的修改,并且修改后不需要重新編譯代碼,也不需要重新部署項目。

⑴.外部化配置的方式

SpringBoot支持多種外部化配置方式,包括但不限于:

  • properties文件

  • YAML文件

  • 系統環境變量

  • 命令行參數

  • ......

⑵.外部化配置的優勢

  1. 靈活性:配置文件可以獨立于應用程序部署,這使得可以根據運行環境的不同來調整配置,而無需修改代碼。

  2. 易于維護:配置變更不需要重新構建和部署應用程序,降低了維護成本。

  3. 安全性:敏感信息如數據庫密碼、API密鑰等可以存儲在外部,并且可以限制誰有權限訪問這些配置信息。

  4. 共享性:多實例或多服務可以共享相同的配置信息,減少重復配置的工作量。

  5. 版本控制:配置文件可以存放在版本控制系統中,便于跟蹤歷史版本和回滾配置。

總之,外部化配置使得配置更加靈活、安全、易于管理和共享,是現代云原生應用中非常推薦的做法

⑶.外部化配置對比傳統配置

在傳統的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

常見的數據存儲和交換格式

propertiesXMLJSONYAML這幾種格式確實是用來存儲和交換數據的常見方式,但它們各有特點和適用場景:

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的語法規則如下:

  1. 數據結構:YAML支持多種數據類型,包括:

    1. 字符串、數字、布爾值

    2. 數組、list集合

    3. map鍵值對 等。

  2. YAML使用一個空格來分隔屬性名屬性值,例如:

    1. properties文件中這樣的配置:name=jack

    2. yaml文件中需要這樣配置:name: jack

  3. YAML用換行+空格來表示層級關系。注意不能使用tab,必須是空格,空格數量無要求,大部分建議2個或4個空格。例如:

    1. properties文件中這樣的配置:myapp.name=mall

    2. 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框架同時支持propertiesyaml

在 Spring Boot 里,當同一個目錄下同時存在application.propertiesapplication.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.propertiesapplication.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對象封裝的主要數據包括:

  1. Active Profiles: 當前激活的配置文件列表。Spring Boot允許應用程序定義不同的環境配置文件(如開發環境、測試環境和生產環境),通過激活不同的配置文件來改變應用程序的行為。

  2. System Properties: 系統屬性,通常是操作系統級別的屬性,比如操作系統名稱、Java版本等。

  3. System Environment Variables: 系統環境變量,這些變量通常是由操作系統提供的,可以在啟動應用程序時設置特定的值。

  4. Command Line Arguments: 應用程序啟動時傳遞給主方法的命令行參數。

  5. 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 + "信息");}
}

編寫切面

測試

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79918.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79918.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79918.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網絡接入服務商查詢

要查詢網站的 網絡接入服務商&#xff08;即網站服務器托管或接入的ISP公司&#xff09;&#xff0c;可以通過以下方法進行查詢&#xff1a; 方法1&#xff1a;通過IP地址查詢 步驟1&#xff1a;獲取網站IP 使用 ping 命令&#xff1a; ping example.com 返回的IP地址即為服務…

超詳細!RxSwift 中的 BehaviorRelay 使用教程(含原理 + 示例 + 實戰)

目錄 前言 1.什么是 BehaviorRelay 2.基本使用方式 3.BehaviorRelay的常用API 4.BehaviorRelay 和其它類型的對比 5.BehaviorRelay的使用場景 1.綁定UITableView 2.MVVM 場景下使用 BehaviorRelay 6.使用注意事項以及建議 1.注意事項 2.使用建議總結 7.推薦閱讀 前…

vue-grid-layout實現拖拽修改工作臺布局

效果圖 vue-grid-layout 文檔地址&#xff1a;vue-grid-layout 官網介紹&#xff1a; 使用 // 安裝&#xff1a; npm install vue-grid-layout --save// 引用&#xff1a; import { GridLayout, GridItem } from vue-grid-layout// 注冊&#xff1a; components:{ GridLay…

windows使用bat腳本激活conda環境

本文不生產技術&#xff0c;只做技術的搬運工&#xff01;&#xff01;&#xff01; 前言 最近需要在windows上使用批處理腳本執行一些python任務&#xff0c;但是被自動激活conda環境給卡住了&#xff0c;研究了一下解決方案 解決方案 call your_conda_path\Scripts\activa…

u-boot學習筆記(四)

文章目錄 cmd/sub_cmd/exit.cdo_exit()exit.c可提供的命令及使用方式&#xff1a; ext2.cdo_ext2ls()do_ext2load()ext2.c可提供的命令及使用方式&#xff1a; ext4.cdo_ext4_size()do_ext4_load()do_ext4_ls()do_ext4_write()ext4.c可提供的命令及使用方式&#xff1a; fastbo…

OpenCV 圖形API(80)圖像與通道拼接函數-----仿射變換函數warpAffine()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 對圖像應用仿射變換。 函數 warpAffine 使用指定的矩陣對源圖像進行變換&#xff1a; dst ( x , y ) src ( M 11 x M 12 y M 13 , M 21 x M…

《React Native熱更新實戰:用Pushy打造無縫升級體驗》

《React Native熱更新實戰:用Pushy打造應用“空中加油”,實現無縫升級體驗》 寫在前面:當你的APP需要"空中加油"時… 想象一下這樣的場景:凌晨2點,你的React Native應用剛上線就爆出重大BUG,用戶差評如潮水般涌來,應用商店審核至少需要3天…此刻你多么希望能…

《社交應用架構生存戰:React Native與Flutter的部署容災決勝法則》

React Native和Flutter作為當下熱門的跨平臺開發框架&#xff0c;在社交應用開發領域各顯神通。今天&#xff0c;我們深入探索它們在高可用架構中的部署與容災策略。 React Native憑借其獨特優勢&#xff0c;在社交應用開發中擁有一席之地。它基于JavaScript和React&#xff0…

網絡靶場基礎知識

一、網絡靶場的核心概念 網絡靶場&#xff08;Cyber Range&#xff09;是一種基于虛擬化和仿真技術的網絡安全訓練與測試平臺&#xff0c;通過模擬真實網絡環境和業務場景&#xff0c;為攻防演練、漏洞驗證、安全測試和人才培養提供安全可控的實驗空間。其核心目標是通過“虛實…

AutoGen 框架解析:微軟開源的多人 Agent 協作新范式

一、引言 在大語言模型&#xff08;LLM&#xff09;快速發展的今天&#xff0c;復雜任務的自動化協作需求日益增長。微軟開源的AutoGen 框架&#xff08;GitHub Star 超 10 萬&#xff09;提供了一種基于多智能體對話的協作范式&#xff0c;通過自然語言交互實現多角色 Agent …

極簡遠程革命:節點小寶 — 無公網IP的極速內網穿透遠程解決方案

極簡遠程革命&#xff1a;節點小寶&#xff0c;讓家庭與職場無縫互聯 ——打破公網桎梏&#xff0c;重塑數字生活新體驗 關鍵詞&#xff1a;節點小寶&#xff5c;內網穿透&#xff5c;P2P直連&#xff5c;家庭網絡&#xff5c;企業協作&#xff5c;智能組網節點小寶&#xff5…

【MySQL】存儲引擎 - CSV詳解

&#x1f4e2;博客主頁&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客倉庫&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01; &…

云原生安全治理體系建設全解:挑戰、框架與落地路徑

??個人主頁??:慌ZHANG-CSDN博客 ????期待您的關注 ???? 一、引言:云原生環境下,安全治理正在被重構 在傳統IT架構中,安全防護多依賴邊界設備(如防火墻、WAF、堡壘機)進行集中式防護。然而,在云原生環境下,這種“邊界式”安全模型正面臨顛覆。 應用微服務化…

SiC MOSFET同步Buck DC-DC變換器的寬頻混合EMI濾波器設計

摘要由于 SiC MOSFET 在高速開關電源中的廣泛應用&#xff0c;導致嚴重的電磁干擾&#xff08;EMI&#xff09;問題&#xff0c;因此 EMI 濾波器的設計成為研究熱點。為了滿足電磁兼容&#xff08;EMC&#xff09;標準&#xff0c;無源 EMI 濾波器可以有效地降低 DC-DC 變換器產…

[java八股文][Java并發編程面試篇]場景

多線程打印奇偶數&#xff0c;怎么控制打印的順序 可以利用wait()和notify()來控制線程的執行順序。 以下是一個基于這種方法的簡單示例&#xff1a; public class PrintOddEven {private static final Object lock new Object();private static int count 1;private stat…

MySQL的索引和事務

目錄 1、索引 1.1 查看索引 1.2 創建索引 1.3 刪除索引 1.4 索引的實現 2、事務 1、索引 索引等同于目錄&#xff0c;屬于針對查詢操作的一個優化手段&#xff0c;可以通過索引來加快查詢的速度&#xff0c;避免針對表進行遍歷。 主鍵、unique和外鍵都是會自動生成索引的…

Qt 驗證自動釋放 + 亂碼問題(6)

文章目錄 驗證自動釋放&#xff08;對象樹上的對象&#xff09;亂碼問題的緣由解決亂碼問題1. 使用QString2. qDebug() 小結 簡介&#xff1a;上一篇文章寫到&#xff0c;當new出一個控件對象并且將它掛到對象樹上&#xff0c;無需我們手動釋放該對象&#xff0c;是因為在一個合…

fastjson2 json.tojsonstring 會自動忽略過濾掉 key: null的數據

如果你想在序列化時保留值為 null 的字段&#xff0c;只要打開 Fastjson2 的 WriteNulls 特性即可。常見做法有兩種——按調用級別開啟&#xff0c;或全局開啟。 1. 在每次序列化時加 WriteNulls import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONWriter…

LeetCode熱題100--54.螺旋矩陣--中等

1. 題目 給你一個 m 行 n 列的矩陣 matrix &#xff0c;請按照 順時針螺旋順序 &#xff0c;返回矩陣中的所有元素。 示例 1&#xff1a; 輸入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 輸出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2&#xff1a; 輸入&#xff1a;ma…

別卷手柄了!跨平臺VR遙操系統實現仿真

我們構建了一個基于 Quest 3 的 VR 遙操系統&#xff0c;該系統能夠同時支持 DISCOVERSE 仿真環境與 MMK2 真機的操控&#xff0c;實現了從虛擬環境到真實機器人系統的無縫對接。 ? 基于 VR 實現的遙操系統具有良好的擴展性和便攜性&#xff0c;為多場景應用提供了靈活的操作方…