今天來聊聊SpringBoot的自動(dòng)配置吧?
面試官:好久沒見,甚是想念。今天來聊聊SpringBoot的自動(dòng)配置吧?
候選者:嗯,SpringBoot的自動(dòng)配置我覺得是SpringBoot很重要的“特性”了。眾所周知,SpringBoot有著“約定大于配置”的理念,這一理念一定程度上可以用“SpringBoot自動(dòng)配置”來解釋。

候選者:SpringBoot自動(dòng)配置的原理理解起來挺簡單的,我們在使用SpringBoot的時(shí)候,肯定會(huì)依賴于autoconfigure這么一個(gè)包
候選者:autoconfigure這個(gè)包里會(huì)有一個(gè)spring.factories文件,該文件定義了100+個(gè)入口的配置類。比如我們經(jīng)常使用的redis、kafka等等這樣常見的中間件都預(yù)置了配置類
候選者:當(dāng)我們在啟動(dòng)SpringBoot項(xiàng)目的時(shí)候,內(nèi)部就會(huì)加載這個(gè)spring.factories文件,進(jìn)而去加載“有需要”的配置類。那我們在使用相關(guān)組件的時(shí)候,就會(huì)非常的方便(因?yàn)榕渲妙愐呀?jīng)初始化了一大部分配置信息)。
候選者:一般我們只要在application配置文件寫上對應(yīng)的配置,就能通過各種template類直接操作對應(yīng)的組件啦。

面試官:那是所有的配置類都會(huì)加載嗎?這個(gè)“有需要”的配置類你是怎么理解的?
候選者:不是所有的配置類都會(huì)加載的,假設(shè)我們沒有引入redis-starter的包,那Redis的配置類就不會(huì)被加載。具體Spring在實(shí)現(xiàn)的時(shí)候就是使用 @ConditionalXXX進(jìn)行判斷的。比如Redis的配置類就會(huì)有@ConditionalOnClass({RedisOperations.class})的配置,說明當(dāng)前環(huán)境下如果有RedisOperations.class這個(gè)字節(jié)碼,才會(huì)去加載Redis的配置類

面試官:哦,這樣啊,那了解了。那你知不知道Redis的配置類其實(shí)會(huì)有初始化RedisTemplate對象的操作,那假設(shè)我們沒有引入redis-starter包,那他是怎么通過編譯的?(當(dāng)然了,其他的配置類也是有可能有一樣的狀況)
候選者:嗯,這個(gè)我看源碼的時(shí)候我也發(fā)現(xiàn)了。其實(shí)就是在autoconfigure包里會(huì)定義到相關(guān)的依賴,但只是標(biāo)記為optional并且只在編譯環(huán)境有效。那這樣是能通過編譯的,只是不會(huì)將其依賴傳入到我們的應(yīng)用工程里。
候選者:這塊還是花了我很多時(shí)間的,我最后在GitHub 的SpringBoot源碼里找到的。
面試官:嗯啊,有點(diǎn)東西的喲。既然都聊到這塊了,要不順便聊聊你對SpringBoot starter的理解?
候選者:嗯,starter這東西就是為了方便調(diào)用方去使用相關(guān)的組件的嘛,Spring框架也給我們實(shí)現(xiàn)了很多好用的starter。
候選者:比如以前我們要用Mybatis框架,可能會(huì)引入各種的包才能使用。而starter就是做了一層封裝,把相關(guān)要用到的jar都給包起來了,并且也寫好了對應(yīng)的版本。這我們使用的時(shí)候就不需要引入一堆jar包且管理版本類似的問題了。

候選者:現(xiàn)在很多開源的組件都會(huì)提供對應(yīng)的springboot-starter包給我們?nèi)ビ?,要做一個(gè)starter包并不難。參照Spring內(nèi)置的實(shí)現(xiàn)就好了:1、在工程里引入 starter 打包相關(guān)的依賴。2、在我們工程內(nèi)建spring.factories文件,編寫我們配置類的全限類名。
面試官:嗯,大致都了解了,可以的。最后聊下你是怎么看這塊源碼的?
候選者:源碼具體大概就不記得了,思路倒是還有的。我先從啟動(dòng)類開始,會(huì)有個(gè)@SpringBootApplication,后面會(huì)定位到一個(gè)自動(dòng)配置的注解@EnableAutoConfiguration,那最后就能看到注解內(nèi)部會(huì)去META-INF/spring.factories加載配置類
候選者:這塊源碼并不難,這個(gè)過程也了解到了原來maven有option和scope這倆標(biāo)簽,但確實(shí)是SpringBoot比較重要的概念吧。
面試官:好嘞,今天到這就結(jié)束了吧。
題外:這個(gè)問題確實(shí)被問到過幾次。說實(shí)在的,對于Spring類、注解的信息我真的記不住。感覺能答出這個(gè)流程思路,也就夠用了(如果面試官確實(shí)是要細(xì)究某個(gè)類名,那這種公司不去也罷)
約定大于配置:SpringBoot給我們內(nèi)置了很多配置類,這些配置類也初始化了很多配置(默認(rèn)值)。當(dāng)我們要使用的時(shí)候,只需要覆蓋這些配置項(xiàng)就完事了。即便我們不寫,大多數(shù)情況下都不需要由我們顯示配置出來,但相關(guān)組件就能正常訪問了。
對線面試官系列繼續(xù)連載啦!還有什么常見的面試題,我還沒寫的,可以在評論區(qū)留言
