《2022問》3:爲什麼 Spring Boot 能夠自動加載並使用默認配置(或自定義配置)初始化 starter 組件?

        號稱幾乎零配置的 Spring Boot 早已成爲了N多開發者的必備工具了,以至於題目的問題有點像在問“爲什麼我的刀能砍柴”,那我肯定會毫不客氣地回答你“我的刀不僅可以砍柴還能砍盔甲”!它就是會自動配置的,項目啓動的時候,項目自動讀取相關配置文件去初始化就行了。

        我們來思考一個問題,我有一個基於 Spring Boot 的組件,張三引用了我這個組件,那麼我這個組件是必然在張三的項目啓動後自動初始化的嗎?如果是,那麼如果某個組件是不需要自動初始化的話,Spring Boot 是會對它自動初始化還是不會初始化呢?要知道,Spring Boot 通常是是使用 Java 配置類來初始化的,是不是每個組件只要有 @Configuration 註解的類都會被自動執行呢?而且,既然某個組件是在項目啓動後自動初始化的,那麼我們又是如何做到在yml之類的配置文件中更改某個組件的初始化參數值的呢?

        其實,Spring Boot 只會知道哪個項目需要自動加載,這是由它提供的一個加載流程決定的,需要自動加載的項目需要按照這個流程去實現,要讓 Spring Boot 能夠按照這個流程最終將這個項目給加載好。

        這個流程是這樣的。

        首先,需要自動加載的項目都要在類路徑下創建一個 META-INFO/spring.factories 文件,否則 Spring Boot 在啓動時不會對這個項目做任何的操作。在 spring.factories 文件中,要有一個名爲 org.springframework.boot.autoconfigure.EnableAutoConfiguration 的參數,它指定了自動加載的 Java 配置類(可以有多個),從命名來看就能知道,這是一個 Spring Boot 在自動加載時所需要用到的參數。簡單說就是,如果這裏沒有這個參數,Spring Boot 也是不知道你要如何初始化自己的項目的,而這個參數所指定的是該項目已經定義好的、有 @Configuration 註解的配置類,它必須包含包名,以下是 RockMQ 中的該配置,可以當作一個示例來看:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.cloud.stream.binder.rocketmq.config.RocketMQComponent4BinderAutoConfiguration

        上面的配置表名,RockMQ 將通過 RocketMQComponent4BinderAutoConfiguration 來實現自動初始化,需要 Spring Boot 項目在啓動的時候執行(贅述一下,如果需要執行多個配置類,那麼就在這裏配置多個,英文逗號隔開),否則 Spring Boot 不會做任何操作。

        在這些配置類中將會去讀取它所需要的配置信息,配置信息的key值需要是全局唯一的;又或者,項目中創建了讀取配置信息的類,通過某個唯一的前綴,將其下的所有配置信息讀取到類中。

@ConfigurationProperties(prefix = "spring.cloud.stream.rocketmq.binder" )

public class RocketMQBinderConfigurationProperties

        上面的配置信息類就獲取了 spring.cloud.stream.rocketmq.binder 前綴下的所有配置信息,這些配置信息是在我們自己創建的項目中自定義配上去的。如果我們的項目中沒有給出相關的配置,那麼它們通常會有默認值,這也是實現“約定大於配置”的過程,它減少了我們學習某個項目的每個配置項的時間,也降低了配置出錯的概率,還統一了配置思路。

        而我們自己做的 Spring Boot 項目需要使用 @EnableAutoConfiguration 註解去啓動自動加載配置,我們通常是使用 @SpringBootApplication 註解,它包含了前者。啓動自動加載後,Spring Boot 會通過 @Import 加載 AutoConfigurationImportSelector 類,這個類再去讀取所有包中的類路徑下的 META-INFO/spring.factories 文件(這裏就對應上了前述的每個項目都自己定義了的該文件),取出 org.springframework.boot.autoconfigure.EnableAutoConfiguration 對應的值並加載這些配置類。

        來到這裏,Spring Boot 就能對相關的項目進行自動加載了,它並沒有使用到什麼特別的技術,實質上只是定義了一個加載流程,所有的項目都只要遵守並實現這個流程,就能使得這個項目在被其他項目引用時達到自動加載的效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章