我們都知道 自動配置是SpringBoot框架最為核心也是最精髓的一點 當你開始創建整個springboot專案的主啟動類 并啟動它的時候 它就自動的將所有你需要配置的給自動配置了,也匯入了相應的組件進入IOC容器,省去了我們之前手動去xml檔案里各種繁瑣的配置,大大的提高了我們專案環境搭建的效率,并且如果你不滿意框架給你的配置,你可以通過它的全域組態檔yml或者propertise來進行修改它的默認配置。
那么springboot是如何做到實作啟動即自動配置的呢?那么我們需要從它主啟動類上的@SpringBootApplication說起。
話不多說 直接上圖。

進去查看這個注解 發現有一個@EnableAutoConfiguration注解 它就是開啟自動配置功能的注解

我們再跟進去這個注解 發現有一個@Import底層注解 它匯入了一個叫做 EnableAutoConfigurationImportSelector 的組件 這個組件就是決定哪些配置類和組件需要匯入我們專案

我們跟進去這個類

再進入它的父類AutoConfigurationImportSelector
發現它呼叫了一個叫做selectImports的方法 去選擇哪些組件和自動配置類我們需要匯入.那么問題就來了,它是去哪里選擇我們的配置類呢?我們可以看到它方法體里面呼叫了一個 getCandidateConfigurations方法 回傳了一個configurations集合 并且整個selectImports方法最終也是回傳了它 所以我猜測自動組態檔的挑選源在哪整個問題的答案應該就在這個getCandidateConfigurations方法中(從英文翻譯“獲取候選的配置”我們也可以很容易遐想到)

話不多說 跟進去看看 發現它是由SpringFactoriesLoader.loadFactoryNames()方法 得到的目標物件

我們可以看到它傳入了一個class類引數 跟進去發現回傳的是EnableAutoConfiguration注解的class物件

我們回傳到上一步 繼續往SpringFactoriesLoader.loadFactoryNames()中跟進去 發現了之前疑問的答案 原來是去類路徑下的META-INF/spring.factories檔案里挑選 掃描所有jar包類路徑下的META-INF/spring.factories檔案

于是我們找到它去掃描jar包的類路徑下的 META-INF/spring.factories檔案
發現的確里面有EnableAutoConfiguration屬性 每一個這樣的 xxxAutoConfiguration類都是容器中的一個組件,通過條件判斷加入到容器中;用他們來做自動配置;

每一個自動配置類進行自動配置功能;
我們隨便找其中一個舉例子:我們找到HttpEncodingAutoConfiguration

發現它上面有一個@EnableConfigurationProperties注解 里面有一個HttpEncodingProperties物件
這個注解的作用就是啟動指定類的ConfigurationProperties功能;將組態檔中對應的值和HttpEncodingProperties系結起來;并把HttpEncodingProperties加入到ioc容器中
我們跟進HttpEncodingProperties物件中 發現有一個我們熟悉的注解@ConfigurationProperties
它不就是將組態檔中對應的值和HttpEncodingProperties系結起來嗎?我們在yml或者propertise組態檔中通過它指定的prefix前綴可以有提示的修改它的默認配置。

然后我們再回到上一步 對HttpEncodingAutoConfiguration配置類上的注解逐一解釋
@Configuration 表示這是一個配置類,以前撰寫的組態檔一樣,也可以給容器中添加組件
@EnableConfigurationProperties(HttpEncodingProperties.class) 啟動指定類的ConfigurationProperties功能;將組態檔中對應的值和HttpEncodingProperties系結起來;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication Spring底層@Conditional注解(Spring注解版),根據不同的條件,如果
滿足指定的條件,整個配置類里面的配置就會生效; 判斷當前應用是否是web應用,如果是,當前配置類生效.
@ConditionalOnClass(CharacterEncodingFilter.class) //判斷當前專案有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing =
true) 判斷組態檔中是否存在某個配置 spring.http.encoding.enabled;如果不存在,判斷也是成立的
即使我們組態檔中不配置pring.http.encoding.enabled=true,也是默認生效的;
如果這些條件注解都生效了,則會給容器中添加組件 這個組件的某些值需要從properties中獲取
而此時這個HttpEncodingProperties已經加入了IOC容器 并和組態檔進行了系結,
所以這個要添加的組件就會從這個HttpEncodingProperties中拿值 最后創建好組件 加入到IOC容器
只有一系列的condition條件注解生效 自動配置類才會生效 才會添加組件 所以不是每個自動配置類都能夠生效的

精髓:
1)、SpringBoot啟動會加載大量的自動配置類
2)、我們看我們需要的功能有沒有SpringBoot默認寫好的自動配置類;
3)、我們再來看這個自動配置類中到底配置了哪些組件;(只要我們要用的組件有,我們就不需要再來配置了)
4)、給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性。我們就可以在組態檔中指定這
些屬性的值.

自動配置類必須在一定的條件下才能生效;
我們怎么知道哪些自動配置類生效;我們可以通過在組態檔中啟用 debug=true屬性;來讓控制臺列印自動配置報告,這樣我們就可以很方便的知道哪些自動配置類生效;

自動配置報告:

不生效的

uj5u.com熱心網友回復:
有啥問題嗎bro轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/223076.html
標籤:Java EE
上一篇:求教!簡單的計算器小程式開發
