您好,登錄后才能下訂單哦!
這篇文章主要介紹“SpringBoot2入門自動配置原理源碼分析”,在日常操作中,相信很多人在SpringBoot2入門自動配置原理源碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”SpringBoot2入門自動配置原理源碼分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
之前為什么會去了解一些底層注解,其實就是為了后續更好的了解 springboot 底層的一些原理,比如自動配置原理。
從 MainApplication 中的@SpringBootApplication
開始。
進入@SpringBootApplication
,可以看到這是一個合成注解(紅框中是要關注的)。
這個注解干嘛的?
直接點進去,發現有一個@Configuration
注解,那這不就是個配置類嘛。
進而也說明了,MainApplication 也是一個配置類。
這個已經很熟悉了,可以指定掃描哪些 Spring 注解。
只不過這里,加了一些其他的過濾條件,暫時不關注。
這個是最重要的注解了,聽名字就不一般,開啟自動配置。
點進去,發現也是一個合成注解(紅框需要關注)。
(1)@AutoConfigurationPackage
聽名字像是自動配置包?依舊點進去。
可以看到原來是導入了一個叫Registrar
的組件,繼續點進 Registrar
。
這里是利用Registrar()
給容器中導入一系列組件,也就是批量注冊組件。
在這里打個斷點,debug 啟動一下。
registerBeanDefinitions()
方法中有個傳參:
metadata
,是注解的元信息,可以看到這個注解是被標注在com.pingguo.boot.MainApplication
。
而在registerBeanDefinitions()
方法體內,new 了一個AutoConfigurationPackages.PackageImports()
,里面傳入的是元注解,通過getPackageNames()
獲取到包名。
AutoConfigurationPackages.register( registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]) );
在 idea 中可以單獨執行下片段代碼(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames()
。
選中右擊,再點擊 Evaluate。
得到的結果就是com.pingguo.boot
。為什么是這個?因為注解標注在MainApplication
類,而這個類就屬于com.pingguo.boot
。
拿到包名之后,封裝到數組里,也就是上述代碼片段中的toArray(new String[0])
,最后注冊進去。
所以,這里的Registrar()
就是把指定的包下的所有組件批量注冊到容器中。
(2)@Import(AutoConfigurationImportSelector.class)
上面指定好默認包規則之后,就需要去導入需要的包了,利用的是AutoConfigurationImportSelector
,繼續點進去看。
這里有個selectImports
方法,這個方法決定了要具體導入哪些,返回的是一個數組。
方法體內,又是調用了getAutoConfigurationEntry()
方法來獲取配置入口,進而再通過getConfigurations()
方法獲取具體配置,最終轉成數組返回。
顯然getAutoConfigurationEntry()
是個重點。
往下翻一點,就是getAutoConfigurationEntry()
的實現,在這里打個斷點(把上面的斷點取消掉)。
debug重新運行一下,往下走到getCandidateConfigurations()
。
這里是獲取所有候選配置,目前可以看到這里是共有 127 個。
為什么是這 127 個?其實是在配置文件里寫死了,在 springboot 啟動時候,給容器加載的所有場景的配置類。
定義的位置是在這:\spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar!\META-INF\spring.factories
雖然這些一股腦的在啟動時候會去加載到容器,但是最終會按需開啟配置。
比如點開aop
,看到@ConditionalOnClass({Advice.class})
這個條件,是當存在Advice
類時候才導入組件,但實際上這里并沒有Advice
。
這就是基于 springboot 的按條件裝配@Conditional
,根據規則最終實現按需裝配。
分別用最終未生效、和生效的自動配置來加深理解。
比如 cache。
可以看到CacheAutoConfiguration
上是加了幾個條件裝配的。
(1)@ConditionalOnClass({CacheManager.class})
在 idea 中使用ctrl+N
搜索一下CacheManager
,發現是存在的,那么這個條件滿足。
(2)@ConditionalOnBean({CacheAspectSupport.class})
這個條件是要求容器中存在CacheAspectSupport
這個組件才可以。
現在來判斷一下是否存在這個組件,在 main 方法里增加測試代碼:
... ... String[] beanNamesForType = run.getBeanNamesForType(CacheAspectSupport.class); System.out.println("==CacheAspectSupport類型組件的數量==" + beanNamesForType.length); ... ...
運行查看輸出。
發現數量等于 0,也就是不存在該類型的組件。
也就是說@ConditionalOnBean({CacheAspectSupport.class})
這個條件不滿足,所以整個類CacheAutoConfiguration
里的配置都不生效。
之前寫過 web 的demo,那么 web 相關的配置自然是生效的,找到它。
這里有不少后綴是**AutoConfiguration
的配置,直接來看DispatcherServletAutoConfiguration
。
@Configuration(proxyBeanMethods = false)
:表示是一個配置類。
@ConditionalOnWebApplication(type = Type.SERVLET)
:條件是否為一個 web 應用,而且是原生 SERVLET 類型的(因為springboot2還有webflux),當前滿足條件。
@ConditionalOnClass({DispatcherServlet.class})
:條件是否導入了DispatcherServlet
類,這里也是有的。
還有 2 個注解直接沒見過,這里不用太多關注,了解一下:
@AutoConfigureOrder:這個配置類的配置優先級順序。@AutoConfigureAfter:表示在xx之后才配置這個類,這里就是在配置完ServletWebServerFactoryAutoConfiguration.class
后,再配置當前的類。
所以,類上的幾個條件都是滿足的,就可以進一步到類中了,繼續往下找:
看到DispatcherServletConfiguration
類上也有條件:
@Conditional({DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition.class}):
別看這么長,其實就是上面的一個類
@ConditionalOnClass({ServletRegistration.class})
: 這個也存在。
@EnableConfigurationProperties({WebMvcProperties.class}):
這個很熟悉了,使用前面剛學習完不久,它并不是條件裝配,而是用來綁定外部配置文件的,點進去。
可以看到,會與配置文件中前綴是spring.mvc
的所有屬性進行綁定。
另外,還可以自動把組件注冊到容器中去。
這里可以試一下,在 main 方法里增加輸出:
String[] beanNamesForType1 = run.getBeanNamesForType(WebMvcProperties.class); System.out.println("==WebMvcProperties類型組件的數量==" + beanNamesForType1.length);
運行一下,果然是有一個:
到此,說明DispatcherServletConfiguration
這個配置類也是生效的。
繼續往下就看到方法dispatcherServlet()
,而且是加了@Bean
注解,就是給容器中注冊DispatcherServlet
類型的組件。
這里的經過是:
new 一個DispatcherServlet()
對象dispatcherServlet
。接著對dispatcherServlet
一通 set 設置。最后返回這個對象dispatcherServlet
。
在之前學習 springMVC 時候,還要手動去設置關于DispatcherServlet
的一堆東西。而在 springboot 里已經在底層設置好了,并且注冊到容器中去了,所以我們能直接使用。
到此,關于“SpringBoot2入門自動配置原理源碼分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。