【Java】springboot的自動配置

????????如果你用過 Spring Boot,一定對 “引入依賴就能用” 的體驗印象深刻 —— 加個spring-boot-starter-web就有了 Web 環境,這個是 SpringBoot 的自動裝配(Auto-Configuration)機制。

自動裝配的核心注解

????????自動裝配的邏輯看似復雜,其實核心流程只有 3 步:觸發自動裝配 → 加載配置類 → 條件篩選組件。

1. 第一步:觸發自動裝配 ——@SpringBootApplication 注解。

????????Spring Boot 應用的啟動類上,都會有一個@SpringBootApplication注解,比如:

@SpringBootApplication
public class SpringBootDemoApplication {public static void main(String[] args) {SpringApplication.run(SpringBootDemoApplication.class, args);}
}

????????這個注解是 “組合注解”,它的核心功能來自其中的 **@EnableAutoConfiguration**注解,觸發了自動裝配的整個流程。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 1. 開啟自動配置(核心)
@EnableAutoConfiguration
// 2. 掃描當前包及子包的Bean(如@Controller、@Service)
@ComponentScan(excludeFilters = { ... })
// 3. 允許在啟動類上定義Bean(如@Bean)
@SpringBootConfiguration
public @interface SpringBootApplication {// 省略屬性...
}

其中,@EnableAutoConfiguration 是自動裝配的 “總開關”,它又依賴兩個關鍵機制:?

  • @Import(AutoConfigurationImportSelector.class):導入一個 “配置選擇器”,負責加載自動配置類;?
  • SpringFactoriesLoader:Spring 的一個工具類,負責從指定文件中加載配置類列表。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}

2. 第二步:加載配置類 —— 從 META-INF/spring.factories 中加載配置

????????AutoConfigurationImportSelector的核心作用,是通過SpringFactoriesLoader,加載classpath 下所有 META-INF/spring.factories 文件中配置的 “自動配置類”。

? ? ? ? (1)什么是 spring.factories??

????????這是一個鍵值對格式的配置文件,Spring Boot 的核心 starter(如mybatis-pus)中就自帶這個文件,路徑在:mybatis-plus-boot-starter\3.5.2\mybatis-plus-boot-starter-3.5.2.jar!\META-INF\spring.factories:

(2)AutoConfigurationImportSelector 的工作流程?

當應用啟動時,AutoConfigurationImportSelector會執行以下操作:?

? ? ? ? 1、調用selectImports()方法,觸發配置類加載;?

// 方法作用:選擇需要導入的自動配置類,返回類的全限定名數組
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 第一步:判斷自動裝配是否啟用// isEnabled方法會檢查@EnableAutoConfiguration注解的啟用狀態if (!this.isEnabled(annotationMetadata)) {// 如果未啟用,返回空數組(NO_IMPORTS是Spring定義的空數組常量)return NO_IMPORTS;} else {// 第二步:獲取自動配置條目(核心邏輯)// 該方法會加載、篩選并確定最終需要生效的配置類AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}

? ? ? ? 2、調用getAutoConfigurationEntry()方法

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} // 獲取 @EnableAutoConfiguration 注解的屬性(如 exclude、excludeName 等)AnnotationAttributes attributes = this.getAttributes(annotationMetadata);// 加載所有候選自動配置類(數據源:META-INF/spring.factories)// 調用我們之前解析過的 getCandidateConfigurations 方法,獲取原始候選配置類列表List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);configurations = this.removeDuplicates(configurations);
spring.autoconfigure.excludeSet<String> exclusions = this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);
@ConditionalOnClass、@ConditionalOnBean)configurations = this.getConfigurationClassFilter().filter(configurations);this.fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}

? ? ? ? 3、調用getCandidateConfigurations()方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 第一個參數:指定加載的工廠類類型(這里是EnableAutoConfiguration.class)// 第二個參數:類加載器(用于讀取類路徑下的資源)List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(),  // 返回EnableAutoConfiguration.classthis.getBeanClassLoader()                    // 獲取當前的類加載器);// 如果為空,拋出異常提示(通常是因為找不到META-INF/spring.factories文件)Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. " +"If you are using a custom packaging, make sure that file is correct.");return configurations;
}protected Class<?> getSpringFactoriesLoaderFactoryClass() {return EnableAutoConfiguration.class;
}

3. 第三步:條件篩選@Conditiona

加載到自動配置類后,Spring Boot 并不是無條件地啟用所有配置,而是通過條件注解進行篩選。

常用的條件注解有:

  • @ConditionalOnClass:當類路徑中存在指定類時生效
  • @ConditionalOnMissingClass:當類路徑中不存在指定類時生效
  • @ConditionalOnBean:當容器中存在指定 Bean 時生效
  • @ConditionalOnMissingBean:當容器中不存在指定 Bean 時生效
  • @ConditionalOnProperty:當指定的屬性有特定值時生效
  • @ConditionalOnWebApplication:當應用是 Web 應用時生效

例如:

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {// 配置內容...
}

自定義自動配置

1、定義我們需要裝配的類

結構:

DataSourceAutoconfiguration類

@Configuration
@EnableConfigurationProperties(DataSourcePropertie.class) // 批量注入
public class DataSourceAutoconfiguration {@Bean()public DataSource dataSource(DataSourcePropertie dataSourcePropertie) {try {ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();comboPooledDataSource.setJdbcUrl(dataSourcePropertie.getJdbcUrl());comboPooledDataSource.setDriverClass(dataSourcePropertie.getDriverName());comboPooledDataSource.setUser(dataSourcePropertie.getUsernames());comboPooledDataSource.setPassword(dataSourcePropertie.getPasswords());return comboPooledDataSource;} catch (PropertyVetoException e) {throw new RuntimeException(e);}}
}

DataSourcePropertie

@ConfigurationProperties(prefix = "datasouce")// 注入前綴為datasouce
public class DataSourcePropertie {private String jdbcUrl = "jdbc:mysql://localhost:3306/summer_practice";private String driverName = "com.mysql.cj.jdbc.Driver";private String usernames = "root1";private String passwords = "1234561";public String getJdbcUrl() {return jdbcUrl;}public void setJdbcUrl(String jdbcUrl) {this.jdbcUrl = jdbcUrl;}public String getDriverName() {return driverName;}public void setDriverName(String driverName) {this.driverName = driverName;}public String getUsernames() {return usernames;}public void setUsernames(String usernames) {this.usernames = usernames;}public String getPasswords() {return passwords;}public void setPasswords(String passwords) {this.passwords = passwords;}
}

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.ape.redisspringbootautoconfigure.DataSourceAutoconfiguration

pom.xml

    </properties><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><!--c3p0--><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>

2、配置咋們的啟動類(我們只需要在pom.xml中導入需要裝配類的坐標)

結構:

pom.xml

        <dependency><groupId>com.ape</groupId><artifactId>redis-spring-boot-autoconfigure</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

3、在啟動類中就可以拿到我們自定義的配置類

@SpringBootApplication
public class SpringbootStarter04Application {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringbootStarter04Application.class, args);DataSource bean = context.getBean(DataSource.class);System.out.println(bean);}}

4、配置文件(可選)

? ? ? ? 由于我們在需要裝配的類中添@EnableConfigurationProperties(DataSourcePropertie.class)該注解,所以我們可以在啟動類中配置yml文件來替換需要裝配的類的數據,從而實現動態的改變其中的數據。

yml

datasouce:usernames: rootpasswords: 123456

總結

????????Spring Boot 的自動裝配機制通過@EnableAutoConfiguration注解、SpringFactoriesLoader加載機制以及條件注解,實現了基于約定的自動配置,極大地簡化了 Spring 應用的開發。允許我們通過自定義配置來覆蓋默認行為,可以實現個性化定制。

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

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

相關文章

高通機型QPST平臺線刷教程 線刷全分區 只通過引導文件提取單分區 寫入單分區

高通芯片機型刷機平臺很多&#xff0c;除過一些廠家專用的平臺外。qpst是高通芯片類通用刷寫平臺。其操作簡單 可以刷寫完整固件。也可以通過單個引導文件來讀取 提取整個分區。而且包含讀寫基帶qcn等等的一些功能。 qpst工具下載 QPST 的不同版本可在多個開源平臺或技術論壇中…

ES_預處理

1. 預處理的核心概念&#xff1a;什么是 Ingest Pipeline&#xff1f; 想象一下數據進入 Elasticsearch 的旅程。原始數據&#xff08;Raw Data&#xff09;往往并不完美&#xff1a;格式可能混亂&#xff0c;字段可能缺失&#xff0c;或者需要被豐富和轉換后才能發揮最大的價值…

我從零開始學習C語言(15)- 基本類型 PART2

開始學習第七章其余部分。7.3.4 轉義序列正如在前面示例中見到的那樣&#xff0c;字符常量通常是用單引號括起來的單個字符。然而&#xff0c;一些特殊符號&#xff08;比如換行符&#xff09;是無法采用上述方式書寫的&#xff0c;因為它們不可見&#xff08;非打印字符&#…

K8S的部署與常用管理

一、k8s的部署 1.1.集群環境初始化 1.1.1.所有主機禁用swap [rootk8s- ~]# systemctl mask dev-nvme0n1p3.swap [rootk8s- ~]# swapoff -a [rootk8s- ~]# systemctl status dev-nvme0n1p3.swap [rootk8s- ~]# vim /etc/fstab 內容&#xff1a; 注釋swap 1.1.2.安裝k8s部署工…

2025年機械工程與自動化技術國際會議(ICMEAT 2025)

2025年機械工程與自動化技術國際會議&#xff08;ICMEAT 2025&#xff09; 2025 International Conference on Mechanical Engineering and Automation Technology一、大會信息會議簡稱&#xff1a;ICMEAT 2025 大會地點&#xff1a;中國杭州 審稿通知&#xff1a;投稿后2-3日內…

高數 不定積分(4-3):分部積分法

文章目錄寫在前面分部積分法&#x1f615; 一個小問題? 分部積分法是怎么來的&#xff1f;&#x1f330; 幾個小例子? 最終總結&#xff01;后話寫在前面 文章傳送門&#xff1a;高數 不定積分&#xff08;4-2&#xff09;&#xff1a;換元積分法 今天再更一篇:) 上篇文章&…

Chrome/360 瀏覽器 WebUI 資源底層機制解析:共享資源與專屬資源的奧秘

在 Chromium 和 360 瀏覽器源碼中&#xff0c;我們會發現 WebUI 頁面不僅有 C 邏輯處理&#xff08;如 WebUIMessageHandler&#xff09;&#xff0c;還伴隨著大量 HTML、CSS 和 JS 文件。尤其是 src/ui/webui/resources 和 src/chrome/browser/360/webui 這兩個目錄&#xff0…

基于springboot的高校后勤保修服務系統/基于android的高校后勤保修服務系統app

基于springboot的高校后勤保修服務系統/基于android的高校后勤保修服務系統app

Qt QML 用Q_PROPERTY快捷訪問c++屬性

在之前我寫過如何調用函數&#xff0c;當時的屬性都是手搓的&#xff0c;也就是自己寫成員變量、變化信號和讀寫函數&#xff0c;但其實有一個很便捷的方法&#xff0c;即使用Q_PROPERTY&#xff0c;下面給出標準結構&#xff1a;Q_PROPERTY(數據類型 變量名 READ 變量名 WRITE…

ubuntu中網卡的 IP 及網關配置設置為永久生效

要將 Ubuntu 中 ens33 和 ens36 網卡的 IP 及網關配置設置為永久生效&#xff08;重啟后不丟失&#xff09;&#xff0c;需通過 netplan 配置并禁用 cloud-init 對網絡的干擾&#xff08;避免重啟后配置被覆蓋&#xff09;&#xff0c;具體步驟如下&#xff1a;一、最終的永久生…

不再讓Windows更新!Edge游戲助手卸載及關閉自動更新

文章目錄Windows系統更新問題方法一&#xff1a;通過注冊表手動設置1. 打開注冊表編輯器2. 定位到目標路徑3. 創建新的DWORD值4. 修改數值方法二&#xff1a;命令行設置1. 打開命令提示符2. 輸入命令驗證設置是否生效恢復更新Edge關閉游戲助手Edge關閉后臺運行Edge關閉自動更新…

css3之flex布局

flex布局要牢記的兩個知識點&#xff1a; 開啟了flex布局的元素叫flex containerflex container里面的直接子元素叫flex items 這兩點要記牢&#xff0c;設置屬性的時候才不會搞混這個是flex布局的整體圖 一、flex container上的屬性 1.flex-direction 修改主軸方向的屬性&…

vscode 搭建C/C++開發環境搭建(linux)

1.編譯器/調試器安裝首先&#xff0c;需要安裝編譯器&#xff08;GCC/G&#xff09;和調試器&#xff08;GDB&#xff09;,用于編譯和調試代碼。1.打開終端(Ctrl Alt T)2.更新軟件包獲取新版本信息sudo apt update3.安裝build-essential包,它包含gcc,g等必要庫sudo apt install…

vue-pure-admin頁面引入和功能添加流程解析

vue-pure-admin (opens new window)是一款開源完全免費且開箱即用的中后臺管理系統模版。完全采用 ECMAScript 模塊&#xff08;ESM&#xff09;規范來編寫和組織代碼&#xff0c;使用了最新的 Vue3、Vite、Element-Plus、TypeScript、Pinia、Tailwindcss 等主流技術開發 以下是…

vlc-android: 編譯自己的libvlc

概述 VLC 媒體播放器作為一款由志愿者開發團隊精心維護的自由、開源且跨平臺的多媒體播放器&#xff0c;能輕松駕馭絕大多數多媒體文件&#xff0c;無論是本地磁盤中的視頻、音頻&#xff0c;還是來自網絡的流媒體協議. VLC for Android 支持網絡串流&#xff0c;無論是基于 H…

并聯諧振與串聯諧振

在LC電路中&#xff0c;感抗和容抗相等時對應的頻率值稱為諧振頻率&#xff0c;在接收廣播電視信號或無線通信信號時&#xff0c;使接收電路的頻率與所選擇的發射的信號頻率相同就叫做調諧。并聯諧振LC并聯諧振電路是指將電感器和電容器并聯形成&#xff0c;如圖所示。在并聯諧…

打印機怎么連接電腦?打印機驅動?【圖文詳解】USB連接打印機?wifi連接打印機?

一、問題背景 在日常辦公與生活里&#xff0c;把電腦和打印機連接起來&#xff0c;是實現文檔、照片等打印的基礎操作。但很多人初次嘗試時&#xff0c;會因不熟悉流程而感到無從下手。 無論是辦公場景下急需打印重要文件&#xff0c;還是日常生活中想要打印照片留念&#xff0…

CVPR 2025 | 醫學影像加速進化:深度學習×多模態,精準診斷再升級

關注gongzhonghao【CVPR頂會精選】今天聊一個醫學圖像領域的前沿探索&#xff1a;結合空間感知卷積、擴散模型與視覺語言模型&#xff0c;從圖像配準到合成分割&#xff0c;再到跨模態理解&#xff0c;打造了一個更加智能、魯棒且可泛化的醫學影像工具鏈。無論是SACB-Net帶來的…

[每周一更]-(第157期):深入理解Go語言的垃圾回收機制:調優與監控

Go語言以其簡潔的語法和強大的并發能力而聞名&#xff0c;而它的垃圾回收&#xff08;GC&#xff09;機制則是支撐其高性能的關鍵組件之一。本文將深入探討Go語言的垃圾回收原理&#xff0c;并介紹如何對其進行調優與監控&#xff0c;以提升應用程序的性能。 Go語言垃圾回收機制…

Java 學習筆記(基礎篇9)

1. 綜合練習題目 1 &#xff1a;金額轉換為中文大寫格式請編寫一個 Java 程序&#xff0c;實現將數字金額轉換為中文大寫格式&#xff08;帶單位&#xff09;的功能&#xff0c;具體要求如下&#xff1a;(1) 程序接收用戶輸入的一個整數金額&#xff08;范圍&#xff1a;0-9999…