更新時間:2022-09-28 來源:黑馬程序員 瀏覽量:
什么是自動配置呢?簡單說就是springboot根據我們開發者的行為猜測你要做什么事情,然后把你要用的bean都給你準備好。聽上去是不是很神奇?其實非常簡單,。springboot咋做到的呢?就是看你導入了什么類,就知道你想干什么了。然后把你有可能要用的bean(注意是有可能)都給你加載好,你直接使用就行了,springboot把所需要的一切工作都做完了。
自動配置的意義就是加速開發效率,將開發者使用某種技術時需要使用的bean根據情況提前加載好,實現自動配置的效果。當然,開發者有可能需要提供必要的參數,比如你要用mysql技術,導入了mysql的坐標,springboot就知道了你要做數據庫操作,一系列的數據庫操作相關的bean都給你提前聲明好,但是你要告訴springboot你到底用哪一個數據庫,P地址,端口,你不告訴spirngbootspringboot就無法幫你把自動配置相關的工作做完。
而這種思想其實就是在日常的開發過程中根據開發者的習慣慢慢抽取得到了。整體過程分為2個階段:
1. springboot的開發人員先大量收集Spring開發者的編程習慣,整理開發過程每一個程序經常使用的技術列表,形成一個技術集A
2. 收集常用技術(技術集A)的使用參數,不管你用什么常用設置,我用什么常用設置,統統收集起來整理一下,得到開發過程中每一個技術的常用設置,形成每一個技術對應的**設置集B**
3. springboot初始化Spring容器基礎環境,讀取用戶的配置信息,加載用戶自定義的bean和導入的其他坐標,形成初始化環境。
4. springboot將技術集A包含的所有技術在SpringBoot啟動時默認全部加載,這時肯定加載的東西有一些是無效的,沒有用的。
5. springboot會對技術集A中每一個技術約定出啟動這個技術對應的條件,并設置成按條件加載,由于開發者導入了一些bean和其他坐標,也就是與初始化環境,這個時候就可以根據這個初始化環境與springboot的技術集A進行比對了,哪個匹配上加載哪個。
6. 因為有些技術不做配置就無法工作,所以springboot開始對設置集B下手了。它統計出各個國家各個行業的開發者使用某個技術時最常用的設置是什么,然后把這些設置作為默認值直接設置好,并告訴開發者當前設置我已經給你搞了一套,你要用可以直接用,這樣可以減少開發者配置參數的工作量。
7. 但是默認配置不一定能解決問題,于是springboot開放修改設置集B的接口,可以由開發者根據需要決定是否覆蓋默認配置。
以上這些僅僅是一個思想,落地到代碼實現階段就要好好思考一下怎么實現了。假定我們想自己實現自動配置的功能,都要做哪些工作呢?首先指定一個技術X,我們打算讓技術X具備自動配置的功能,這個技術X可以是任意功能,這個技術隸屬于上面描述的技術集A。具體的實現代碼如下:
public class CartoonCatAndMouse{ }
然后找出技術X使用過程中的常用配置Y,這個配置隸屬于上面表述的設置集B
yaml cartoon: cat: name: "圖多蓋洛" age: 5 mouse: name: "泰菲" age: 1
將常用配置Y設計出對應的yml配置書寫格式,然后定義一個屬性類封裝對應的配置屬性,這個過程其實就是上一節咱們做的bean的依賴屬性管理,一模一樣。
@ConfigurationProperties(prefix = "cartoon") @Data public class CartoonProperties { private Cat cat; private Mouse mouse; }
最后做一個配置類,當這個類加載的時候就可以初始化對應的功能bean,并且可以加載到對應的配置。
@EnableConfigurationProperties(CartoonProperties.class) public class CartoonCatAndMouse implements ApplicationContextAware { private CartoonProperties cartoonProperties; }
當然,你也可以為當前自動配置類設置上激活條件,例如使用@CondtionOn為其設置加載條件
@ConditionalOnClass(name="org.springframework.data.redis.core.RedisOperations") @EnableConfigurationProperties(CartoonProperties.class) public class CartoonCatAndMouse implements ApplicationContextAware { private CartoonProperties cartoonProperties; }
到這里就算配置完畢了,但是遇到了一個全新的問題,如何讓springboot啟動的時候去加載這個類呢?如果不加載的話,我們做的條件判定,做的屬性加載這些全部都失效了。
springboot為我們開放了一個配置入口,在配置目錄中創建META-INF目錄,并創建spring.factories文件,在其中添加設置,說明哪些類要啟動自動配置就可以了。
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.itheima.bean.CartoonCatAndMouse
其實這個文件就做了一件事,通過這種配置的方式加載了指定的類。轉了一圈,就是個普通的bean的加載,和最初使用xml格式加載bean幾乎沒有區別,格式變了而已。那自動配置的核心究竟是什么呢?自動配置其實是一個小的生態,可以按照如下思想理解:
1. 自動配置從根本上來說就是一個bean的加載
2. 通過bean加載條件的控制給開發者一種感覺,自動配置是自適應的,可以根據情況自己判定,但實際上就是最普通的分支語句的應用,這是蒙蔽我們雙眼的第一層面紗。
3. 使用bean的時候,如果不設置屬性,就有默認值,如果不想用默認值,就可以自己設置,也就是可以修改部分或者全部參數,感覺這個過程好屌,也是一種自適應的形式,其實還是需要使用分支語句來做判斷的,這是蒙蔽我們雙眼的第二層面紗
4. springboot技術提前將大量開發者有可能使用的技術提前做好了,條件也寫好了,用的時候你導入了一個坐標,對應技術就可以使用了,其實就是提前幫我們把spring.factories文件寫好了,這是蒙蔽我們雙眼的第三層面紗
你在不知道自動配置這個知識的情況下,經過上面這一二三,你當然覺得自動配置是一種特別牛的技術,但是一窺究竟后發現,也就那么回事。而且現在springboot程序啟動時,在后臺偷偷的做了這么多次檢測,這么多種情況判定,不用問了,效率一定是非常低的,畢竟它要檢測100余種技術是否在你程序中使用。
1. springboot啟動時先加載spring.factories文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration配置項,將其中配置的所有的類都加載成bean
2. 在加載bean的時候,bean對應的類定義上都設置有加載條件,因此有可能加載成功,也可能條件檢測失敗不加載bean
3. 對于可以正常加載成bean的類,通常會通過@EnableConfigurationProperties注解初始化對應的配置屬性類并加載對應的配置
4. 配置屬性類上通常會通過@ConfigurationProperties加載指定前綴的配置,當然這些配置通常都有默認值。如果沒有默認值,就強制你必須配置后使用了