深入淺析SpringBoot自動配置原理
SpringBoot2.3.1版本源碼
一、SpringBoot啟動的時候加載主配置類,通過@EnableAutoConfiguration註解開啟瞭自動配置功能 。
二、@EnableAutoConfiguration作用:
1、 點擊該註解進入可以發現,它利用AutoConfigurationImportSelector.class 選擇器給SpringBoot導入一些組件。導入哪些組件呢?可以點擊選擇器進入查看selectImports()方法的內容,該方法最終會返回一個configurations。
2、selectImports方法調用瞭getAutoConfigurationEntry()方法獲取自動配置實體,在getAutoConfigurationEntry()方法中有一條代碼
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
用於獲取候選的配置
其中getCandidateConfigurations()方法有一條代碼
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
從類路徑下得到一個資源,loadFactoryNames()方法中→loadSpringFactories()方法→classLoader.getResources(“META-INF/spring.factories”),掃描所有jar包類路徑下的META-INF/spring.factories的文件
loadSpringFactories()方法通過如下代碼:
Enumeration<URL>urls=classLoader!=null?classLoader.getResources("META-INF/spring.factories")
得到META-INF/spring.factories文件的URL,然後把每一個URL遍歷,最終通過Propertiesproperties=PropertiesLoaderUtils.loadProperties(resource);把這些文件封裝成一個properties對象,然後從properties對象中獲取一些值,把每一個url獲取到的值添加到最終要返回的結果中。而這些返回結果就是我們要交給容器中的所有組件。其中factoryTypeName指的就是傳過來的Class的類名,而傳過來的class是從AutoConfigurationImportSelector類的getCandidateConfigurations()方法的this.getSpringFactoriesLoaderFactoryClass()中得到的,其返回值是EnableAutoConfiguration.class意思就是從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,然後把他們添加在容器中。
在spring-boot-autoconfigure-2.3.1.RELEASE.jar!\META-INF\spring.factories文件中,我們可以找到EnableAutoConfiguration的值
所以相當於把EnableAutoConfiguration值裡面的這些組件加到瞭容器中。
簡而言之就是:將類路徑下\META-INF\spring.factories裡面配置的所有EnableAutoConfiguration的值加入到瞭容器中。所以最終容器中會添加很多的類,這些就是自動配置之源,自動配置的開始 。 每一個xxxAutoConfiguration類(自動配置類)都是容器中的一個組件,都加入到容器中,用他們來做自動配置。
三、每一個自動配置類進行自動配置功能
以HttpEncodingAutoConfiguration(Http編碼自動配置)自動配置類為例解釋自動配置原理
@Configuration( //這是一個配置類,就類似配置文件一樣,也可以給容器中添加組件 proxyBeanMethods = false ) @EnableConfigurationProperties({ServerProperties.class}) //啟用指定類(ServerProperties.class)的EnableConfigurationProperties功能; 將配置文件中對應的值和ServerProperties類綁定起來,並把ServerProperties加入到IOC容器中。 @ConditionalOnWebApplication( //底層使用的是Spring底層的Conditional註解,根據不同的條件,如果滿足指定的條件, 整個配置類裡面的配置才會生效。ConditionalOnWebApplication:判斷當前應用是否是web應用,如果是,當前配置類生效。 type = Type.SERVLET ) @ConditionalOnClass({CharacterEncodingFilter.class}) //判斷當前項目有沒有CharacterEncodingFilter這個類,(SpringMVC中進行亂碼解決的過濾器),如果有,當前配置類生效。 @ConditionalOnProperty( //判斷配置文件中是否存在某個配置,server.servlet.encoding.enabled, matchIfMissing = true表示,如果不存在判斷也是成立的。(即使配置文件中不配置server.servlet.encoding.enabled,也是默認生效的) prefix = "server.servlet.encoding", value = {"enabled"}, matchIfMissing = true ) public class HttpEncodingAutoConfiguration { private final Encoding properties;//properties屬性已經和SpringBoot的配置文件映射瞭。 public HttpEncodingAutoConfiguration(ServerProperties properties) { //隻有一個有參構造器的情況下,參數的值就會從容器中拿 this.properties = properties.getServlet().getEncoding(); } @Bean//給容器中添加一個組件,這個組件的某些值需要從properties中獲取。 @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST)); //需要使用什麼編碼就從Encoding類的properties屬性中獲取 filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE)); return filter; }
簡而言之:xxxAutoConfiguration自動配置類就是根據當前不同條件判斷,決定這個配置類是否生效。
那如果這些判斷都成功瞭,配置類生效瞭,接下來怎麼辦呢?
一旦這個配置類生效, 接下來這個配置類會通過@Bean註解給容器中添加各種組件,這些組件的屬性是從對應的xxxProperties類中獲取的,而這個類裡面的每一個屬性又是和配置文件綁定的
ServerProperties.class類
@ConfigurationProperties(//從配置文件中獲取指定的值,和ServerProperties類的屬性進行綁定 prefix = "server", ignoreUnknownFields = true ) public class ServerProperties {
所以說,我們在配置文件中應該配置什麼,就按照她的旨意,根據 prefix = “server”我們可以知道,在配置文件中可以配server這個屬性。而server屬性裡面能配置什麼值,就看ServerProperties.class類中有哪些屬性。
ServerProperties中有的這些屬性,都可以在配置文件中配置。
例如:server.port server.address
四、由此我們可以知道,所有能在配置文件中配置的屬性都是在xxxProperties類中封裝著,
配置文件能配置就可以參照某一個功能對應的這個xxxProperties類。
精髓:
1)、SpringBoot啟動會加載大量的自動配置類xxxAutoConfiguration
2)、我們看我們需要的功能有沒有SpringBoot寫好的自動配置類
3)、我們再來看這些自動配置類到底配置瞭哪些組件;(隻要我們要用的組件有,我們就不需要再來配置瞭)如果沒有,我們就需要自己寫配置類。
4)、給容器中自動配置類添加組件的時候,會從xxxPropertiess類中獲取某些屬性,我們就可以在配置文件中指定這些屬性的值
自動配置中最重要的兩種類:
xxxAutoConfiguration:自動配置類給容器中添加組件
xxxProperties:封裝配置文件中相關的屬性
到此這篇關於SpringBoot自動配置原理的文章就介紹到這瞭,更多相關SpringBoot自動配置原理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringBoot如何自定義starter
- springboot自定義starter方法及註解實例
- Java SpringBoot自動裝配原理詳解及源碼註釋
- SpringBoot自動配置深入探究實現原理
- SpringBoot自動配置特點與原理詳細分析