Spring Boot自動配置原理深度解析:從條件注解到spring.factories

大家好!今天我們來深入探討Spring Boot最神奇的特性之一——自動配置(Auto-configuration)。這個功能讓Spring Boot如此受歡迎,因為它大大簡化了我們的開發工作。讓我們一起來揭開它的神秘面紗吧!👀

🌟 什么是自動配置?

想象一下,你剛搬進一個新家🏠。如果是傳統Spring,你需要自己買家具、安裝電器、布置每個房間。而Spring Boot就像一家提供"精裝修"服務的公司——當你搬進去時,冰箱🍔、洗衣機👕、電視📺都已經安裝好了,而且都是根據你的生活習慣智能選擇的!

這就是自動配置的魔力?——它根據你項目中的依賴和配置,自動為你配置好Spring應用所需的大部分組件。

�? 自動配置的核心原理

自動配置的實現依賴于幾個關鍵技術和概念:

1. @EnableAutoConfiguration注解

這是啟動自動配置的"開關"🔛。當你在主類上使用@SpringBootApplication時,它實際上包含了@EnableAutoConfiguration

@SpringBootApplication  // 這里面就包含了@EnableAutoConfiguration
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}

2. spring.factories文件

這是自動配置的"地圖"🗺?。Spring Boot在META-INF/spring.factories文件中查找所有自動配置類。

# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration,\
com.example.AnotherAutoConfiguration

3. 條件注解(Conditional Annotations)

這些是自動配置的"決策大腦"🧠,決定是否應該應用某個配置。常見的條件注解包括:

  • @ConditionalOnClass:當類路徑上有指定類時生效
  • @ConditionalOnMissingBean:當容器中沒有指定Bean時生效
  • @ConditionalOnProperty:當配置屬性滿足條件時生效
  • @ConditionalOnWebApplication:當是Web應用時生效

🔬 深入自動配置流程

讓我們看看Spring Boot是如何實現自動配置的:

  1. 啟動階段🚦:

    • Spring Boot應用啟動
    • @SpringBootApplication觸發自動配置
  2. 加載自動配置類📦:

    • Spring Boot掃描所有jar包中的META-INF/spring.factories文件
    • 加載org.springframework.boot.autoconfigure.EnableAutoConfiguration鍵下所有的配置類
  3. 過濾自動配置類🧹:

    • 根據各種條件注解過濾掉不適用的配置類
    • 只保留符合條件的配置類
  4. 應用配置??:

    • 將最終篩選出的配置類應用到Spring容器中
    • 創建并注冊各種Bean

🧩 條件注解詳解

條件注解是自動配置的核心機制,讓我們詳細看看幾個重要的:

@ConditionalOnClass

@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {// 只有當DataSource類在類路徑上時,這個配置才會生效
}

@ConditionalOnMissingBean

@Bean
@ConditionalOnMissingBean
public MyService myService() {// 只有當容器中沒有MyService類型的Bean時,才會創建這個默認的MyServicereturn new DefaultMyService();
}

@ConditionalOnProperty

@Configuration
@ConditionalOnProperty(prefix = "myapp", name = "enabled", havingValue = "true")
public class MyAppAutoConfiguration {// 只有當myapp.enabled=true時,這個配置才會生效
}

@ConditionalOnWebApplication

@Configuration
@ConditionalOnWebApplication
public class WebMvcAutoConfiguration {// 只有當應用是Web應用時,這個配置才會生效
}

🛠? 自動配置實戰:自定義Starter

理解了原理后,讓我們動手創建一個自定義的Spring Boot Starter!

1. 創建自動配置模塊

@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {@Autowiredprivate MyServiceProperties properties;@Bean@ConditionalOnMissingBeanpublic MyService myService() {return new MyService(properties.getPrefix(), properties.getSuffix());}
}

2. 創建配置屬性類

@ConfigurationProperties("my.service")
public class MyServiceProperties {private String prefix;private String suffix;// getters and setters
}

3. 注冊自動配置類

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

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

4. 打包發布

現在,其他項目只需要引入你的starter依賴,就可以自動獲得MyService的配置了!

🔍 自動配置的調試技巧

有時候我們需要了解為什么某個自動配置沒有生效,Spring Boot提供了幾種調試方式:

  1. 啟用調試日志📝:
    application.properties中添加:

    debug=true
    

    啟動時會打印自動配置報告。

  2. 使用ConditionEvaluationReport📊:
    可以通過注入ConditionEvaluationReport來獲取詳細的條件評估報告。

  3. 使用Spring Boot Actuator👨??:
    /actuator/conditions端點提供了詳細的自動配置條件信息。

?? 自動配置的優缺點

優點:

  • 快速啟動?:無需手動配置大量樣板代碼
  • 一致性🔄:所有項目使用相同的默認配置
  • 靈活性🧘:可以通過屬性文件輕松覆蓋默認配置
  • 模塊化🧩:每個starter提供一組相關的自動配置

缺點:

  • 黑盒效應📦:新手可能不理解背后的機制
  • 調試困難🐛:當自動配置不符合預期時,可能需要深入理解原理
  • 啟動時間?:評估大量條件注解可能增加啟動時間

🎓 最佳實踐

  1. 理解默認配置🧠:
    在使用一個starter前,最好了解它提供了哪些自動配置。

  2. 合理覆蓋配置??:
    只在必要時覆蓋自動配置,保持一致性。

  3. 創建自己的starter🛠?:
    當有一組相關的配置和Bean時,考慮創建自己的starter。

  4. 利用條件注解🎚?:
    在自己的配置中也使用條件注解,使配置更加靈活。

  5. 監控自動配置👀:
    定期檢查自動配置報告,確保配置符合預期。

🌰 實際案例:DataSource自動配置

讓我們看一個實際的自動配置例子——DataSourceAutoConfiguration

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {@Configuration@Conditional(EmbeddedDatabaseCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import(EmbeddedDataSourceConfiguration.class)protected static class EmbeddedDatabaseConfiguration {}@Configuration@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,DataSourceConfiguration.Dbcp2.class,DataSourceConfiguration.Generic.class })protected static class PooledDataSourceConfiguration {}// ...
}

這個自動配置類展示了幾個關鍵點:

  1. 只有在類路徑上有DataSourceEmbeddedDatabaseType時才生效
  2. 導入了屬性配置DataSourceProperties
  3. 根據條件選擇嵌入式數據庫或連接池數據庫
  4. 支持多種連接池實現(Hikari, Tomcat, Dbcp2等)

🕵? 如何查看生效的自動配置

Spring Boot提供了幾種方式來查看哪些自動配置生效了:

  1. 使用Actuator

    curl http://localhost:8080/actuator/conditions
    
  2. 啟用調試模式
    在application.properties中添加:

    debug=true
    

    啟動時會打印自動配置報告。

  3. 使用Spring Boot Tools
    許多IDE(如IntelliJ IDEA)提供了Spring Boot工具窗口,可以查看自動配置。

🔄 自動配置與顯式配置的關系

自動配置并不是要完全取代顯式配置,而是與之協同工作:

  1. 自動配置先執行🏃?♂?:
    Spring Boot會先嘗試自動配置

  2. 顯式配置可以覆蓋自動配置🖌?:
    你的@Bean定義會覆蓋自動配置提供的Bean

  3. 條件注解確保靈活性??:
    自動配置通常帶有@ConditionalOnMissingBean,允許你提供自己的實現

🧪 測試自動配置

測試自動配置需要特殊考慮:

  1. 使用@SpringBootTest

    @SpringBootTest
    public class MyAutoConfigurationTests {@Autowired(required = false)private MyService myService;@Testpublic void testServiceAutoConfigured() {assertNotNull(myService);}
    }
    
  2. 測試特定條件

    @Test
    public void testConditionalOnClass() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();EnvironmentTestUtils.addEnvironment(context, "some.property:true");context.register(MyAutoConfiguration.class);context.refresh();assertTrue(context.containsBean("myBean"));
    }
    

🚀 性能優化技巧

自動配置雖然方便,但也可能影響啟動性能:

  1. 減少不必要的starter??:
    只引入真正需要的starter依賴

  2. 延遲初始化??:
    在application.properties中設置:

    spring.main.lazy-initialization=true
    
  3. 使用@ComponentScan限制🎯:
    精確指定掃描路徑,避免不必要的類掃描

  4. 排除自動配置🚫:
    使用@SpringBootApplication的exclude屬性:

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    

📚 深入學習資源

如果你想更深入地學習Spring Boot自動配置:

  1. 官方文檔📄:
    Spring Boot Auto-configuration Docs

  2. 源碼學習👨💻:
    閱讀spring-boot-autoconfigure模塊的源碼

  3. 相關技術🔗:

    • Spring Framework的@Conditional機制
    • Spring的Environment抽象
    • Spring的BeanDefinition體系

🎯 總結

Spring Boot的自動配置是一個強大而復雜的系統,它通過以下方式工作:

  1. 使用@EnableAutoConfiguration觸發自動配置過程
  2. 通過spring.factories發現所有潛在的自動配置類
  3. 利用各種條件注解過濾出適用的配置
  4. 將最終篩選出的配置應用到Spring容器中

理解自動配置原理不僅能幫助你更好地使用Spring Boot,還能讓你在遇到問題時更快地定位和解決。希望這篇文章能幫助你深入理解這個強大的特性!💪

記住,自動配置的目標是約定優于配置——它提供了一套合理的默認值,但你總是可以根據需要覆蓋這些默認值。這就是Spring Boot既強大又靈活的秘密所在!🔑

Happy coding! 🚀👨💻

推薦閱讀文章

  • 由 Spring 靜態注入引發的一個線上T0級別事故(真的以后得避坑)

  • 如何理解 HTTP 是無狀態的,以及它與 Cookie 和 Session 之間的聯系

  • HTTP、HTTPS、Cookie 和 Session 之間的關系

  • 什么是 Cookie?簡單介紹與使用方法

  • 什么是 Session?如何應用?

  • 使用 Spring 框架構建 MVC 應用程序:初學者教程

  • 有缺陷的 Java 代碼:Java 開發人員最常犯的 10 大錯誤

  • 如何理解應用 Java 多線程與并發編程?

  • 把握Java泛型的藝術:協變、逆變與不可變性一網打盡

  • Java Spring 中常用的 @PostConstruct 注解使用總結

  • 如何理解線程安全這個概念?

  • 理解 Java 橋接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加載 SpringMVC 組件

  • “在什么情況下類需要實現 Serializable,什么情況下又不需要(一)?”

  • “避免序列化災難:掌握實現 Serializable 的真相!(二)”

  • 如何自定義一個自己的 Spring Boot Starter 組件(從入門到實踐)

  • 解密 Redis:如何通過 IO 多路復用征服高并發挑戰!

  • 線程 vs 虛擬線程:深入理解及區別

  • 深度解讀 JDK 8、JDK 11、JDK 17 和 JDK 21 的區別

  • 10大程序員提升代碼優雅度的必殺技,瞬間讓你成為團隊寵兒!

  • “打破重復代碼的魔咒:使用 Function 接口在 Java 8 中實現優雅重構!”

  • Java 中消除 If-else 技巧總結

  • 線程池的核心參數配置(僅供參考)

  • 【人工智能】聊聊Transformer,深度學習的一股清流(13)

  • Java 枚舉的幾個常用技巧,你可以試著用用

  • 由 Spring 靜態注入引發的一個線上T0級別事故(真的以后得避坑)

  • 如何理解 HTTP 是無狀態的,以及它與 Cookie 和 Session 之間的聯系

  • HTTP、HTTPS、Cookie 和 Session 之間的關系

  • 使用 Spring 框架構建 MVC 應用程序:初學者教程

  • 有缺陷的 Java 代碼:Java 開發人員最常犯的 10 大錯誤

  • Java Spring 中常用的 @PostConstruct 注解使用總結

  • 線程 vs 虛擬線程:深入理解及區別

  • 深度解讀 JDK 8、JDK 11、JDK 17 和 JDK 21 的區別

  • 10大程序員提升代碼優雅度的必殺技,瞬間讓你成為團隊寵兒!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 為什么用了 @Builder 反而報錯?深入理解 Lombok 的“暗坑”與解決方案(二)

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

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

相關文章

【ELF2學習板】利用OpenMP采用多核并行技術提升FFTW的性能

目錄 引言 OpenMP簡介 編譯OpenMP支持的FFTW庫 部署與測試 測試程序 程序部署 測試結果 結語 引言 在前面已經介紹了在ELF2開發板上運行FFTW計算FFT。今天嘗試利用RK3588的多核運算能力來加速FFT運算。FFTW利用多核能力可以考慮使用多線程或者OpenMP。今天介紹一下Ope…

2000-2017年各省城市天然氣供氣總量數據

2000-2017年各省城市天然氣供氣總量數據 1、時間:2000-2017年 2、來源:國家統計局、能源年鑒 3、指標:行政區劃代碼、城市、年份、城市天然氣供氣總量 4、范圍:31省 5、指標說明:城市天然氣供氣總量是指在一定時間…

Hadoop的三大結構及其作用?

Hadoop是一個分布式存儲和計算框架,其三大核心組件是HDFS(Hadoop Distributed File System)、YARN(Yet Another Resource Negotiator)和MapReduce。它們各自有著重要的作用,共同構成了Hadoop生態系統的基礎…

【AI論文】ColorBench:視覺語言模型能否看到并理解多彩的世界?一個全面的色彩感知、推理和魯棒性基準測試

摘要:顏色在人類感知中起著重要作用,通常在視覺推理中提供關鍵線索。 然而,尚不清楚視覺語言模型(VLMs)是否以及如何像人類一樣感知、理解和利用顏色。 本文介紹了ColorBench,這是一個精心設計的創新基準&a…

Python番外——常用的包功能講解和分類組合

目錄 1. Web開發框架與工具 2. 數據處理與分析 3. 網絡請求與爬蟲 4. 異步編程 5. 數據庫操作 6. 圖像與多媒體處理 7. 語言模型與NLP 8. 安全與加密 9. 配置與工具 10. 其他工具庫 11.典型組合場景 此章節主要是記錄我所使用的包,以及模塊。方便供自己方…

華碩原廠系統槍神9/9p超竟版-WIN11原裝開箱出廠系統安裝

華碩原廠系統槍神9/9p超竟版-WIN11-24H2-專業工作站版本安裝可帶F12-ASUSRecovery恢復功能 適用機型: G635LX、G635LW、G835LX、G835LW、G615LW、G615LP、G615LM、G615LH G815LW、G815LP、G815LM、G815LH、G635LR、G835LR、G615LR、G815LR 遠程恢復安裝&#xff…

拉取windows的docker鏡像轉到服務器上構建服務鏡像

在windows上將拉取ubuntu的docker鏡像轉到服務器上 1.要求 1.1 要求windows和服務器安裝好docker 2.拉取ubuntu鏡像到windows(dos操作,可能需要連接到外網) 一旦你選擇了一個合適的基礎鏡像,你可以使用docker pull命令從Docke…

T1結構像+RS-fMRI影像處理過程記錄(數據下載+Matlab工具箱+數據處理)

最近需要仿真研究T1結構像RS-fMRI影像融合處理輸出目標坐標的路線可行性。就此機會記錄下來。 為了完成驗證目標處理,首先需要有數據,然后需要準備對應的處理平臺和工具箱,進行一系列。那么開始記錄~ 前言: 為了基于種子點的功能連…

Nginx-前言

nginx是什么? 輕量級,開源免費的web服務器軟件,服務器安裝nginx,服務器則成為web服務器 nginx的穩定版版本號: 偶數版本 nginx的相關目錄: /etc/nginx/nginx.conf nginx的主配置文件 /etc/nginx/ngi…

緩慢前行,靜待花開

最期待的不是成品出爐,而是揉面時感受到溫度、發酵時聞到淡淡香氣 1 “慢就是穩,穩就是快”。 這句來自特種兵的訓練語,被許多自媒體人奉為準則。 在看似風云突變的環境下,速度被隱藏在穩定中,結果被醞釀在過程里。…

洛谷的幾道題(2)

P1008 [NOIP 1998 普及組] 三連擊 # P1008 [NOIP 1998 普及組] 三連擊 ## 題目背景 本題為提交答案題,您可以寫程序或手算在本機上算出答案后,直接提交答案文本,也可提交答案生成程序。 ## 題目描述 將 $1, 2, \ldots , 9$ 共 $9$ 個數分…

Day10【基于encoder- decoder架構實現新聞文本摘要的提取】

實現新聞文本摘要的提取 1. 概述與背景2.參數配置3.數據準備4.數據加載5.主程序6.預測評估7.生成效果8.總結 1. 概述與背景 新聞摘要生成是自然語言處理(NLP)中的一個重要任務,其目標是自動從長篇的新聞文章中提取出簡潔、準確的摘要。近年來…

【大疆dji】ESDK開發環境搭建(軟件準備篇)

接上一篇【大疆dji】ESDK開發環境搭建(硬件準備篇) 1. 編譯環境 ESDK 提供 x86_64/aarch64 基于 Linux 平臺 Ubuntu 發行版操作系統構建的靜態庫,運行 demo 先正確安裝所需的依賴包。arm32位就不支持了。建議使用編譯安裝的方式,…

Java數據結構——ArrayList

Java中ArrayList 一 ArrayList的簡介二 ArrayList的構造方法三 ArrayList常用方法1.add()方法2.remove()方法3.get()和set()方法4.index()方法5.subList截取方法 四 ArrayList的遍歷for循環遍歷增強for循環(for each)迭代器遍歷 ArrayList問題及其思考 前言 ArrayList是一種 順…

【信息獲取能力】

第一層:表象觀察 現象:AI系統(如GPT-4)可以瞬間調用并整合全球互聯網上的公開信息,而人類即使窮盡一生也無法完成同等規模的知識儲備。 底層邏輯: 存儲與檢索效率:人類大腦的記憶容量有限&…

03、GPIO外設(三):標準庫代碼示例

標準庫代碼示例 1、點亮LED2、LED閃爍3、LED流水燈4、按鍵控制LED5、蜂鳴器 本章源代碼鏈接: 鏈接: link 1、點亮LED 實驗要求:點亮LED ①LED.c文件的代碼如下: #include "LED.h"/*** LED引腳初始化*//* 定義數組,想要添加引腳…

卷積神經網絡(CNN)與VGG16在圖像識別中的實驗設計與思路

卷積神經網絡(CNN)與VGG16在圖像識別中的實驗設計與思路 以下從基礎原理、VGG16架構解析、實驗設計步驟三個層面展開說明,結合代碼示例與關鍵參數設置,幫助理解其應用邏輯。 一、CNN與VGG16的核心差異 基礎CNN結構 通常包含33~55個…

java導出word含表格并且帶圖片

背景 我們需要通過 Java 動態導出 Word 文檔,基于預定義的 模板文件(如 .docx 格式)。模板中包含 表格,程序需要完成以下操作: 替換模板中的文本(如占位符 ${設備類型} 等)。 替換模板中的圖…

Oracle19C低版本一天遭遇兩BUG(ORA-04031/ORA-600)

昨天幫朋友看一個系統異常卡頓的案例,在這里分享給大家 環境:Exadata X8M 數據庫版本19.11 1.系統報錯信息 表象為系統卡頓,頁面無法刷出,登陸到主機上看到節點1 系統等待存在大量的 cursor: pin S wait on X等待 查看兩個節…

2025年Q1數據安全政策、規范、標準以及報告匯總共92份(附下載)

一、政策演進趨勢分析 (一)國家級政策新動向 數據要素市場建設 數據流通安全治理方案(重點解析數據確權與交易規則) 公共數據授權運營規范(創新性提出分級授權機制) 新興技術安全規范 人工智能安全標準…