Spring之我見 - Spring Boot Starter 自動裝配原理

?歡迎光臨小站:致橡樹

Spring Boot Starter 的核心設計理念是 約定優于配置,其核心實現基于 自動配置(Auto-Configuration)條件化注冊(Conditional Registration)。以下是其生效原理:

約定大于配置

通過預定義合理的默認行為和規范,減少開發者需要手動配置的步驟。比較顯著的變化就是減少XML配置。還有一些實際體現如下所示:

  • 項目結構約定

    • 默認目錄結構:如 src/main/java 存放代碼,src/main/resources 存放配置文件。

    • 配置文件命名application.propertiesapplication.yml 自動被加載,無需顯式指定路徑。

  • 自動配置(Auto-Configuration)

    • 條件化 Bean 注冊:根據類路徑依賴(如存在 DataSource 類)自動配置數據庫連接池

    • 默認參數值:如嵌入式 Tomcat 默認端口為 8080,無需手動指定。

  • Starter 依賴

    • 依賴聚合:引入 spring-boot-starter-web 即自動包含 Web 開發所需的所有依賴(如 Tomcat、Jackson、Spring MVC)。

    • 開箱即用:無需手動管理版本兼容性。

  • RESTful 路由映射

    • 注解驅動:通過 @GetMapping("/path") 即可定義接口,無需在 XML 中配置路由規則。

自動配置機制

觸發階段:@EnableAutoConfiguration

  • 應用啟動時,@SpringBootApplication 組合了 @EnableAutoConfiguration,觸發自動配置流程。

  • AutoConfigurationImportSelector 被調用,負責加載所有候選的自動配置類。

public String[] selectImports(AnnotationMetadata metadata) {// 1. 加載所有候選自動配置類List<String> configurations = getCandidateConfigurations();// 2. 去重、過濾、排序configurations = removeDuplicates(configurations);configurations = filter(configurations, autoConfigurationMetadata);return configurations.toArray(new String[0]);
}

加載與篩選:spring.factories

  • 加載所有候選配置類
    從所有 META-INF/spring.factories 文件中讀取 EnableAutoConfiguration 對應的配置類。在 Spring Boot 3.x 中,自動配置類的加載方式從 spring.factories 過渡到 AutoConfiguration.imports,并引入了 ImportCandidates 類來處理這一變化。

  • 去重與過濾
    移除重復的配置類,并通過條件注解(如 @ConditionalOnClass ,@ConditionalOnMissingBean ) 有選擇的保留當前環境的配置類。

    • @ConditionalOnClass:類路徑存在指定類時生效

    • @ConditionalOnMissingBean:容器中不存在指定 Bean 時生效

    • @ConditionalOnProperty:配置屬性匹配時生效

  • 排序
    根據 @AutoConfigureOrder@AutoConfigureAfter 調整配置類的加載順序。

Bean 注冊

  • 篩選后的自動配置類被解析為標準的 @Configuration 類。

  • 每個配置類中的 @Bean 方法根據條件注解動態注冊 Bean 到 Spring 容器。

編寫自定義Spring Boot Starter

項目結構規劃

建議分為兩個模塊:

  1. 自動配置模塊:包含核心邏輯和自動配置類(如 hello-spring-boot-autoconfigure)。

  2. Starter模塊:空項目,僅作為依賴聚合(如 hello-spring-boot-starter)。

hello-spring-boot-starter-parent(父POM)
├── hello-spring-boot-autoconfigure(自動配置模塊)
└── hello-spring-boot-starter(Starter模塊)
hello-spring-boot-starter/
├── hello-spring-boot-autoconfigure/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/example/autoconfigure/
│   │   │   │   ├── HelloAutoConfiguration.java
│   │   │   │   ├── HelloProperties.java
│   │   │   │   └── HelloService.java
│   │   │   └── resources/
│   │   │       └── META-INF/
│   │   │           └── spring.factories
│   │   └── test/
│   └── pom.xml
├── hello-spring-boot-starter/
│   └── pom.xml
└── pom.xml

創建自動配置模塊(hello-spring-boot-autoconfigure)

添加Maven依賴

<!-- pom.xml -->
<dependencies><!-- Spring Boot 自動配置基礎依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>3.1.5</version></dependency><!-- 可選:配置屬性處理 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><version>3.1.5</version><optional>true</optional></dependency>
</dependencies>

定義核心服務類

public class HelloService {private String message = "Hello, World!";  // 默認消息public String sayHello() {return message;}// Getter和Setter用于通過配置修改messagepublic String getMessage() { return message; }public void setMessage(String message) { this.message = message; }
}

定義配置屬性類(可選)

@ConfigurationProperties(prefix = "hello")
public class HelloProperties {private String message = "Hello, World!";// Getter和Setterpublic String getMessage() { return message; }public void setMessage(String message) { this.message = message; }
}

編寫自動配置類

@Configuration
@EnableConfigurationProperties(HelloProperties.class)  // 啟用配置屬性
@ConditionalOnClass(HelloService.class)  // 當HelloService在類路徑時生效
public class HelloAutoConfiguration {@Bean@ConditionalOnMissingBean  // 當用戶未自定義HelloService時生效public HelloService helloService(HelloProperties properties) {HelloService service = new HelloService();service.setMessage(properties.getMessage());return service;}
}

注冊自動配置

resources/META-INF/ 下創建 spring.factories 文件:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.HelloAutoConfiguration

創建Starter模塊(hello-spring-boot-starter)

添加Maven依賴

<!-- pom.xml -->
<dependencies><!-- 引入自動配置模塊 --><dependency><groupId>com.example</groupId><artifactId>hello-spring-boot-autoconfigure</artifactId><version>1.0.0</version></dependency>
</dependencies>

使用自定義Starter

在應用中引入Starter依賴

<!-- 用戶項目的pom.xml -->
<dependency><groupId>com.example</groupId><artifactId>hello-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>

在代碼中注入Bean

@RestController
public class HelloController {@Autowiredprivate HelloService helloService;@GetMapping("/hello")public String hello() {return helloService.sayHello();}
}

自定義配置(可選)

application.properties 中修改消息:

hello.message=你好, Spring Boot!

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

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

相關文章

精益數據分析(7/126):打破創業幻想,擁抱數據驅動

精益數據分析&#xff08;7/126&#xff09;&#xff1a;打破創業幻想&#xff0c;擁抱數據驅動 在創業的道路上&#xff0c;我們都懷揣著夢想&#xff0c;但往往容易陷入自我編織的幻想中。我希望通過和大家一起學習《精益數據分析》&#xff0c;能幫助我們更清醒地認識創業過…

牛客java練習題

[toc] 1.依賴注入 依賴注入是一種設計模式和編程思想,不依賴 具體的框架實現,可以通過多種方式和框架來實現可以通過Spring , Google Guice , PicoContainer 等都可以實現依賴注入,也可以通過手動編寫實現目的: 為了解耦合,將對象之間的依賴關系從代碼中解耦出來, 使系統更加…

大模型應用開發自學筆記

理論學習地址&#xff1a; https://zh.d2l.ai/chapter_linear-networks/index.html autodl學術加速&#xff1a; source /etc/network_turboconda常見操作: 刪除&#xff1a; conda remove --name myenv --all -y導出&#xff1a; conda env export > environment.yml…

鴻蒙ArkUI實戰之TextArea組件、RichEditor組件、RichText組件、Search組件的使用

本文接上篇繼續更新ArkUI中組件的使用&#xff0c;本文介紹的組件有TextArea組件、RichEditor組件、RichText組件、Search組件&#xff0c;這幾個組件的使用對應特定場景&#xff0c;使用時更加需要注意根據需求去使用 TextArea組件 官方文檔&#xff1a; TextArea-文本與輸…

除了`String`、`StringBuffer` 和 `StringBuilder`之外,還有什么處理字符串的方法?

一、標準庫中的字符串處理類 1. StringJoiner&#xff08;Java 8&#xff09; 用途&#xff1a;用于在拼接字符串時自動添加分隔符、前綴和后綴。示例&#xff1a;StringJoiner sj new StringJoiner(", ", "[", "]"); sj.add("A").…

Qt中讀寫結構體字節數據

在Qt中讀寫結構體字節數據通常涉及將結構體轉換為字節數組(QByteArray)或直接從內存中讀寫。以下是幾種常見方法&#xff1a; 方法1&#xff1a;使用QDataStream讀寫結構體 cpp #include <QFile> #include <QDataStream>// 定義結構體 #pragma pack(push, 1) //…

Windows 10 上安裝 Spring Boot CLI詳細步驟

在 Windows 10 上安裝 Spring Boot CLI 可以通過以下幾種方式完成。以下是詳細的步驟說明&#xff1a; 1. 手動安裝&#xff08;推薦&#xff09; 步驟 1&#xff1a;下載 Spring Boot CLI 訪問 Spring Boot CLI 官方發布頁面。下載最新版本的 .zip 文件&#xff08;例如 sp…

Unity3D仿星露谷物語開發37之澆水動畫

1、目標 當點擊水壺時&#xff0c;實現澆水的動畫。同時有一個水從水壺中流出來的特效。 假如某個grid被澆過了&#xff0c;則不能再澆水了。。 如果某個grid沒有被dug過&#xff0c;也不能被澆水。 2、優化Settings.cs腳本 增加如下內容&#xff1a; public static float…

【2】Kubernetes 架構總覽

Kubernetes 架構總覽 主節點與工作節點 主節點 Kubernetes 的主節點&#xff08;Master&#xff09;是組成集群控制平面的關鍵部分&#xff0c;負責整個集群的調度、狀態管理和決策。控制平面由多個核心組件構成&#xff0c;包括&#xff1a; kube-apiserver&#xff1a;集…

如何對docker鏡像存在的gosu安全漏洞進行修復——筑夢之路

這里以mysql的官方鏡像為例進行說明&#xff0c;主要流程為&#xff1a; 1. 分析鏡像存在的安全漏洞具體是什么 2. 根據分析結果有針對性地進行修復處理 3. 基于當前鏡像進行修復安全漏洞并復核驗證 # 鏡像地址mysql:8.0.42 安全漏洞現狀分析 dockerhub網站上獲取該鏡像的…

【Tauri2】026——Tauri+Webassembly

前言 不多廢話 直言的說&#xff0c;筆者看到這篇文章大佬的文章 【04】Tauri 入門篇 - 集成 WebAssembly - 知乎https://zhuanlan.zhihu.com/p/533025312嘗試集成一下WebAssembly&#xff0c;直接開始 正文 準備工作 新建一個項目 安裝 vite的rsw插件和rsw pnpm instal…

OpenHarmony Camera開發指導(五):相機預覽功能(ArkTS)

預覽是在相機啟動后實時顯示場景畫面&#xff0c;通常在拍照和錄像前執行。 開發步驟 創建預覽Surface 如果想在屏幕上顯示預覽畫面&#xff0c;一般由XComponent組件為預覽流提供Surface&#xff08;通過XComponent的getXcomponentSurfaceId方法獲取surfaceid&#xff09;&…

puzzle(0531)腦力航跡

目錄 腦力航跡 規則 解法 簡單模式 中等模式 困難模式 專家模式 腦力航跡 規則 2條航跡會產生一個相對航跡&#xff1a; 根據相對航跡和其中一個航跡推導另外一個航跡。 解法 沒有任何需要推理的地方&#xff0c;就是純粹的2個矢量相加。 簡單模式 中等模式 困難模…

在win上安裝Ubuntu安裝Anaconda(linx環境)

一&#xff0c;安裝Ubuntu 1. 在 Microsoft 商城去下載Ubuntu(LTS:是長期維護的版本) 2.安裝完之后啟動程序&#xff0c;再重新打開一個黑窗口&#xff1a; wsl --list --verbose 3.關閉Ubuntu wsl --shutdown Ubuntu-22.04 WSL2 Ubuntu-20.04文件太占c盤空間&#xff0c;…

NEAT 算法解決 Lunar Lander 問題:從理論到實踐

NEAT 算法解決 Lunar Lander 問題:從理論到實踐 0. 前言1. 定義環境2. 配置 NEAT3. 解決 Lunar lander 問題小結系列鏈接0. 前言 在使用 NEAT 解決強化學習問題一節所用的方法只適用于較簡單的強化學習 (reinforcement learning, RL) 環境。在更復雜的環境中使用同樣的進化解…

【KWDB 創作者計劃】_上位機知識篇---ESP32-S3Arduino

文章目錄 前言1. ESP32-S3核心特性2. 開發環境搭建(1) 安裝Arduino IDE(2) 添加ESP32-S3支持(3) 選擇開發板(4) 關鍵配置3. 基礎代碼示例(1) 串口通信(USB/硬件串口)(2) Wi-Fi連接(3) 藍牙LE廣播4. 高級功能開發(1) USB OTG功能(2) AI加速(MicroTensorFlow)(3) 雙核任務處理…

JavaScript學習教程,從入門到精通,DOM節點操作語法知識點及案例詳解(21)

DOM節點操作語法知識點及案例詳解 一、語法知識點 1. 獲取節點 // 通過ID獲取 const element document.getElementById(idName);// 通過類名獲取&#xff08;返回HTMLCollection&#xff09; const elements document.getElementsByClassName(className);// 通過標簽名獲取…

PCA 降維實戰:從原理到電信客戶流失數據應用

一、簡介 在機器學習領域&#xff0c;數據的特征維度往往較高&#xff0c;這不僅會增加計算的復雜度&#xff0c;還可能導致過擬合等問題。主成分分析&#xff08;Principal Component Analysis&#xff0c;簡稱 PCA&#xff09;作為一種經典的降維技術&#xff0c;能夠在保留數…

信創時代編程開發語言選擇指南:國產替代背景下的技術路徑與實踐建議

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…

Arcgis10.1的漢化包及破解文件分享

Arcgis10.1的漢化包分享 網上有好多10.2的漢化包&#xff0c;但是10.1的漢化包很少&#xff0c;特在此分析出來給大家 Arcgis10.1破解文件及漢化包: (訪問密碼: 9784) license manager破解安裝文件 另外也分享了license manager破解安裝文件&#xff0c;也在相同的分享鏈接里…