Spring Boot啟動了幾個(gè)IoC容器?如何證明?
你好,我是YourBatman:當(dāng)我老了,也寫代碼;不為別的,只為愛好。
??前言
不少面試者說Spring Boot和傳統(tǒng)Spring/Spring MVC一樣,對又不對。比如IoC容器Spring Boot只用一個(gè),而傳統(tǒng)的Spring MVC一般都是2個(gè);比如Spring Boot不建議你使用@EnableWebMvc注解,而這在傳統(tǒng)Spring MVC項(xiàng)目里幾乎是必須的。
2017年之后,Spring Boot以不可擋之勢在國內(nèi)逐漸成為主流,本文這個(gè)問題就基于Spring Boot環(huán)境的。
?正文
Ioc,即“控制反轉(zhuǎn)”,它不是一種技術(shù),而是一種設(shè)計(jì)思想。Spring框架對此提供了完整實(shí)現(xiàn),并早已成為事實(shí)標(biāo)準(zhǔn)。
IoC的實(shí)現(xiàn)框架不只有Spring,比較著名還有Google的的Guice
理解IoC容器,是進(jìn)階Spring Boot源碼的基礎(chǔ)中的基礎(chǔ),那就先從這個(gè)問題開始吧:Spring Boot啟動了幾個(gè)IoC容器?如何證明?
啟動了幾個(gè)IoC容器?
1個(gè)
Tips:在傳統(tǒng)Spring MVC環(huán)境,這個(gè)答案是1或者2;在Spring Cloud環(huán)境,答案可以是1、2、3、4...都有可能
如何證明?
如何證明才是本問題的核心嘛,否則即使上面?zhèn)€數(shù)答對了也會被認(rèn)為是蒙的。
大部分問題都可以從兩個(gè)方向上來給出證明,這就像證明某個(gè)物理/化學(xué)現(xiàn)象時(shí),可以通過實(shí)驗(yàn)結(jié)果證明,另外也可以從書本的理論(在編程領(lǐng)域也就是源代碼)上“證明”。
從結(jié)果上證明
我準(zhǔn)備了一個(gè)典型的 Spring Boot項(xiàng)目:

為了驗(yàn)證這些這些Bean都來自同一個(gè)IoC容器,這里用到了ApplicationContextAware接口,就像這樣:
實(shí)現(xiàn)了接口ApplicationContextAware的Bean,IoC容器會在初始化此Bean時(shí)回調(diào)setApplicationContext方法,將自己“傳進(jìn)去”。換句話講:哪個(gè)IoC容器初始化了此Bean就傳入哪個(gè)IoC容器,這不正是我們想要證明的事嘛
啟動Spring Boot,控制臺輸出:
地址值一模一樣。因此可得出結(jié)論:這些Bean都來自同一個(gè)IoC容器,從而“間接”證明了Spring Boot只啟動一個(gè)IoC容器。
擴(kuò)展:從結(jié)果上證明的其它方式
從結(jié)果上證明,筆者上面舉例的方式是最推薦的方式。但畢竟表現(xiàn)方式可以有多種,這里再做簡單例舉:
★通過依賴注入方式注入ApplicationContext進(jìn)行比較,就像這樣:
理論依據(jù):若只有一個(gè)IoC容器,任何地方注入的ApplicationContext都應(yīng)該是同一個(gè)。
★★通過Bean之間互相依賴注入,看是否能正常啟動,就像這樣:
理論依據(jù):不同IoC容器之間的Bean是隔離,不能互相注入。
父子容器:子容器可以注入父容器的Bean,反之不行
從源碼上“證明”
Spring Boot啟動過程核心,源代碼都在SpringApplication#run這里:

步驟的具體詳情就不展開了,太枯燥了。有興趣的可看我之前文章的源碼解析,也可看別人的或者B站的。
總之,在應(yīng)用中的Spring,IoC容器要想“啟動”都會調(diào)用refresh()方法,而Spring Boot有且僅會調(diào)用1次這個(gè)方法,所以可證明:Spring Boot有且只啟動了1個(gè)IoC容器。
??總結(jié)
如果Spring家族沒有推出Spring Boot,Spring是有被取代風(fēng)險(xiǎn)的,因?yàn)槟菚r(shí)的開發(fā)者對它的配置繁瑣、使用曲線較高已有所反感(即使比EJB還輕太多)。
Spring Boot橫空出世的宗旨就一個(gè):讓一切變得簡單,一個(gè)框架、一個(gè)入口、一個(gè)IoC容器(摒棄復(fù)雜的父子容器概念),大大降低了使用復(fù)雜度。迅速普及,從而鞏固了Spring的霸主地位,不可撼動。
復(fù)雜度不可能憑空消失,Spring Boot只是將它留給了自己,這不正是優(yōu)秀框架該有的樣子嘛































