Spring-Boot-Starter 學習筆記(1)

来源:https://www.cnblogs.com/cndada/archive/2023/09/27/17733009.html
-Advertisement-
Play Games

Spring-Boot-Starter 1. 準備配置類和 Bean 對象 Spring Boot 提供了兩個註解: @Configuration:Spring 提供的配置類註解,作用在類上,代表整個類是個 Spring 配置類,對照傳統的 Spring XML 配置文件。 @Bean:作用於方法上 ...


Spring-Boot-Starter

1. 準備配置類和 Bean 對象

Spring Boot 提供了兩個註解:

  • @Configuration:Spring 提供的配置類註解,作用在類上,代表整個類是個 Spring 配置類,對照傳統的 Spring XML 配置文件。
  • @Bean:作用於方法上,代表此方法的返回值(對象)將會被 Spring 容器所管理,從而完成 Bean 的自動註冊。

這兩個組合起來搭配可以完美的代替傳統的 Spring XML 配置文件,並給 Spring Boot 的自動配置提供基本數據體。

2. 自動配置條件依賴

有些情況下自動配置類並不是在任何條件下都能生效的,此時我們需要制定自動配置生效的條件,可以使用 Spring Boot 提供的註解來指定生效條件。

這些註解是 spring boot 特有的,常見的條件依賴註解有:

註解 功能說明
@ConditionalOnBean 僅在當前上下文中存在某個 bean 時,才會實例化這個 Bean
@ConditionalOnClass 某個 class 位於類路徑上,才會實例化這個 Bean
@ConditionalOnExpression 當表達式為 true 的時候,才會實例化這個 Bean
@ConditionalOnMissingBean 僅在當前上下文中不存在某個 bean 時,才會實例化這個 Bean
@ConditionalOnMissingClass 某個 class 在類路徑上不存在的時候,才會實例化這個 Bean
@ConditionalOnNotWebApplication 不是 web 應用時才會實例化這個 Bean
@AutoConfigureAfter 在某個 Bean 完成自動配置後實例化這個 Bean
@AutoConfigureBefore 在某個 Bean 完成自動配置前實例化這個 Bean

3. Bean 的參數獲取

舉個例子,例如在 Spring Boot Web 項目中,我們經常會導入 MyBatis 相關的依賴,幫助我們與資料庫打交道,那麼在傳統的 Spring 項目中,我們一般會在 Spring 容器配置 XML 文件中去使用 <bean> 標簽生成相關數據源(DataSource),那麼這個 DataSource 需要我們提供資料庫連接參數:driver、url、username、password 這四個最基本的參數,這些數據可能放在一個叫做 db.properties 文件中,這種文件我們稱為外部數據源文件,在 Spring 配置文件中聲明:<context:property-placeholder location="classpath:db.properties"/>

這樣就可以引入文件中的配置參數了,從而賦值給 DataSource 這個 Bean 所需要的屬性參數。最後完成對象初始化。

這個過程在傳統 Spring 開發,無疑是略顯繁瑣,如果在某些我們需要自定義類和大量參數屬性從外部文件引入,這個時候 properties 文件格式也比較複雜,文件可能較多,在初始化 Bean 時,需要手寫大量的屬性賦值。

那麼 Spring Boot 提供了註解幫助我們減小開發量,更加規範 Bean 參數的獲取方式。

預設情況下我們 Bean 的參數配置在 application.yml 文件中,使用 YAML 文件格式定義,比 properties 文件更有層級感,更簡約。

搭配 @EnableConfigurationProperties、@ConfigurationProperties 這兩個註解可以直接實現自動配置類的 Bean 參數獲取。

3.1 @EnableConfigurationProperties 註解

這個註解使用情況:自動配置類中需要從外部文件獲取參數,來進行初始化。

在註解中指定一個類,這個時候可以配置類可以在這個類中獲取到外部文件的參數,交給配置類中的 Bean 進行初始化。

3.2 @ConfigurationProperties 註解

註解使用情況:從外部文件獲取參數信息,載入到自身類屬性中,給 Spring 配置類提供外部數據來源,外部數據文件通常指的是 application.yml

在註解中指定從 application.yml 文件獲取的首碼,例如 @ConfigurationProperties(prefix="spring.datasource"),會獲取以這個字元串為首碼的所有參數進行自動匹配賦值。

所以可以看出兩個註解的關係是:

@EnableConfigurationProperties 註解作用在配置類中,並且使得該註解指定的數據文件類中的 @ConfigurationProperties 註解生效。

4. Bean 的發現

4.1 自己項目的 Bean 掃描

在寫 Spring Boot 項目時,一般在項目的代碼的根目錄會有一個 Spring Boot 啟動類:xxxApplication.java,這個類被 @SpringBootApplication 註解修飾標記成 Spring Boot 項目的啟動類。

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

此時再來看看如何完成 Bean 掃描,我們需要查看 @SpringBootApplication 註解源碼:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    //...
}

我們重點查看 @SpringBootConfiguration 註解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

可以看到這個註解被熟悉的 @Configuration 註解修飾。@SpringBootConfiguration 應用標註在某個類上說明這個類是SpringBoot 的主配置類,SpringBoot 需要運行這個類的 main 方法來啟動 SpringBoot 應用。

底層 Spring Boot 會幫我們將啟動類的當前路徑包以及子包的所有 Spring 組件(可能需要 @ComponentScan註解去做組件掃描)以及 Bean 掃描初始化。暫時只說淺層的流程,後續會深入 Spring 源碼學習。

4.2 jar 包的 Bean 掃描

那麼前面聊了自己項目的 Bean 掃描,且 Spring Boot 預設掃描啟動類所在包下的主類與子類的所有組件,其中並沒有包括項目依賴包中的類,那麼這些類是如何被 Spring Boot 發現的呢?

這就是第二個主要註解:@EnableAutoConfiguration,開啟自動配置:

這裡引入其他博客的理解,覺得這幾句話簡單易懂:

一、@EnableAutoConfiguration 的作用
簡單點說就是 Spring Boot 根據依賴中的 jar 包,自動選擇實例化某些配置,配置類必須有 @Configuration 註解。

說白了,還是實例化對象,只是實例化的是依賴包中的類。

另外,我們也可以按照自動裝配的規範自己定義裝配的類。

接下來查看一下註解源碼:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    //...
}

主要看 @Import({AutoConfigurationImportSelector.class}),這個註解導入了 AutoConfigurationImportSelector.class 這個類(如果是其他版本,可能會是 @EnableAutoConfigurationImportSelector 這個是子類)。

image-20230924102323579

我們找到 getCandidateConfigurations() 方法,這個方法就是用來載入依賴所需要的自動配置相關。

看到 SpringFactoriesLoader.loadFactoryNames() 的源碼:

image-20230924102840726

其他版本可能是只有 loadFactoryNames() 方法,但是我們主要關註 classLoader.getResources() 方法中的常量:

image-20230924103000135

很明顯這個方法是用來載入資源文件,而這個 Spring 工廠資源的路徑就是依賴中自動配置的相關路徑,根據這個路徑找到需要自動配置的類,最後完成依賴的自動配置。我們導入 mybatis-spring-boot-starter 依賴看看這個 META-INF/spring.factories 裡邊是怎麼樣的:

image-20230924103430699

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

簡單概括的流程:Spring Boot 會根據 jar 包的 META-INF/spring.factories 文件的配置進行自動裝配,裝配的流程是 SpringFactoriesLoader.loadFactoryNames() 方法頂層實現的(底層實現需深入源碼),而開始外部自動裝配的註解是:@SpringBootApplication 註解中的 @Import({AutoConfigurationImportSelector.class})

主導整個過程。

5. Bean 的載入

在 Spring Boot 中將一個普通類交給 Spring 容器管理,通常有以下幾個方法:

  1. 使用 @Configuration 配合 @Bean 註解使用(配置類)。
  2. 使用 @Controller、@Service、@Repository、@Component 註解標註類並且使用 @ComponentScan 自動掃描(組件掃描)。
  3. 使用 @Import 方法(載入外部依賴的類)。

在上面可以看到 Spring Boot 實現自動配置使用的是 @Import 註解這種方式。AutoConfigurationImportSelector 類的 selectImports() 方法(其中調用了 getAutoConfigurationEntry() 方法主要過程)返回一組從 META-INF/spring.factories 文件中讀取的 Bean 的全限定名,這樣 Spring Boot 就可以載入到這些 Bean 並完成實例的初始化工作。

自動配置總結

經過前面的分析,將自動配置的關鍵步驟以及對應註解抽取出來:

  1. 定義需要自動裝配的類信息:@Configuration、@Bean,Spring Boot 配置類。
  2. 設置自動配置條件依賴:@Conditional
  3. 將外部配置文件讀取並封裝成 Bean,讓配置類讀取參數:@EnableConfigurationProperties、@ConfigurationProperties
  4. 實現 Bean 的發現與載入:@EnableAutoConfiguration、@Import

以上的內容是基於其他相關博客內容的基礎,進行自己的學習記錄,接下來需要自定義一個 Spring Boot Starter 來進一步加深理解,後續可能還需要對 Spring 、Spring Boot 的源碼進行學習。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 生在國旗下,長在春風裡!國慶將至,採黎為大家帶來 定製頭像2.0(國慶頭像),讓我們用代碼的形式為祖國慶生!歡迎大家點贊收藏加關註哦 前言 想看效果或者想定製春節頭像的小伙伴請直奔 效果區域; 想一睹定製頭像2.0小工具的原理及實現思路請 ...
  • 在前端面試中,一般比較側重JavaScript方面的考察,CSS佈局方面考察的內容會相對少一些,其中display: none與visibility: hidden的區別是較常見的考點,這兩個css配置都可以從視覺上隱藏DOM元素,那這兩者的使用上有什麼區別呢? ...
  • 全文約 5100 字,預計閱讀需要 15 分鐘。 JavaScript 運行時是指執行 JavaScript 代碼的環境。目前,JavaScript 生態中有三大運行時:Node.js、Bun、Deno。老牌運行時 Node.js 的霸主地位正受到 Deno 和 Bun 的挑戰,下麵就來看看這三個 ...
  • 這是我在博客園的第一篇博客,也是我人生中的第一篇博客。希望它能夠記錄我的成長,幫助更多的人。 最近在寫我們社團的社團網站,有一個頁面不太希望普通訪客能訪問到,所以想做一個“統一身份驗證驗證”,但是又苦於社團網站搭建是純靜態站,沒法做資料庫,只能妥協,將賬號密碼字元串組寫到JavaScript腳本里, ...
  • 說明: 輪播圖在前端開發中是一種常見的元素,通常用於展示一系列的圖片或者內容,並通過滑動或者點擊的方式進行切換。使用JavaScript來實現輪播圖有以下幾個意義: 提升用戶體驗:輪播圖可以在有限的空間內展示更多的內容,為用戶提供更多的信息。同時,輪播圖也具有較好的視覺效果,可以吸引用戶的註意力。 ...
  • 隨著業務的發展,前端項目承載了越來越多的職責,也越來越複雜,簡單通過 cli 生成的框架結構越來越無法滿足。 面對前端項目複雜度的不斷提升,我們開始思考前端的架構組織方式怎麼才更合理?應該如何設計良好的前端架構?行業是否有比較好的優秀實踐? 本文先從架構基本概念開始介紹,然後介紹整潔架構的概念和設計... ...
  • SpringBoot項目的分層 SpringBoot框架項目一般分為五層: View層:向用戶展示頁面 Controller層:前後端交互層,接收前端請求,調用Service層中的方法,接收Service層返回的數據並將其返回到前端。 Service層:存放業務處理的邏輯,以及一些操作資料庫的介面 ...
  • 1.創建獨立開發虛擬環境 1.1虛擬環境簡介 我們編寫的程式,有時用到的Python庫是不一樣的,比如說開發桌面應用程式我們主要用到PyQt5相關的Python庫、開發Web應用程式我們主要用到Django相關的Python庫等等。假設我們在開發桌面應用程式的時候除了PyQt5相關的Python庫外 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...