一篇文章吃透Spring Bean,從入門到裝逼全搞定!
1.引言
大家好,我是小米,一個愛敲代碼、愛喝奶茶、愛分享的 31 歲程序員大哥哥。
前幾天,我去參加了一家大廠的社招面試,碰巧面試官劈頭蓋臉就問了我一個“經(jīng)典老八股”——
“你能說一下什么是 Spring Beans 嗎?”
我當時笑了笑,心想這題我太熟了,Spring 是我最早接觸的框架之一,從 Spring 到 SpringBoot,再到 SpringCloud,一路陪我走到現(xiàn)在,真的是有感情了。
所以這篇文章,我就來和大家分享下我當時是怎么回答的(當然現(xiàn)場比這個簡潔點,面試后我又回憶整理了很多擴展知識),希望能幫到正在面試的你,或者正在系統(tǒng)學習 Spring 的你。
2.先來點小故事:我和 Spring Beans 的初相遇
還記得我剛?cè)肼毜谝患夜荆菚r候還在用 Spring,XML 配置漫天飛,我那時剛學完 JavaSE,聽說要學 Spring,直接有點頭大。
有一天師傅拍著我的肩說:
“小米啊,這一段代碼是配置 Spring Beans 的,咱們系統(tǒng)中最重要的就是 Bean 了,搞懂了你就能走上人生巔峰。”
我當時一臉懵:“Bean 是什么?是綠豆嗎?”
師傅翻了個白眼:“你可以理解成是 Spring 世界里的一切,配置里定義的每個 Java 對象,都叫 Bean。”
當時我就記住了:Bean 是 Spring 中的核心組件,是被 Spring 容器管理的對象。
3.一句話定義 Spring Bean
在正式講概念之前,我們先來一段“官方范式”答法,這是我在面試時的開場白:
Spring Bean 是由 Spring IoC 容器實例化、組裝和管理的對象,通常是應用程序中的核心組件。我們可以通過 XML、注解或者 Java 配置的方式將普通的 Java 類聲明為 Spring Bean,由容器來統(tǒng)一管理它的生命周期和依賴關系。
是不是有點官方?別急,接下來我會把它掰開揉碎,一點點講清楚。
4.為什么要有 Bean?
咱們開發(fā)的時候,難道不是 new 一個對象就好了?為什么非要讓 Spring 管理呢?
舉個例子:
圖片
很普通,對吧?可是一旦業(yè)務復雜了:
- 對象之間依賴越來越多
- 管理生命周期越來越麻煩
- 想要解耦、替換實現(xiàn)越來越難
Spring 就站出來說:“別擔心,我來幫你統(tǒng)一創(chuàng)建這些對象,還幫你把它們組裝起來。”
于是就有了 IoC(控制反轉(zhuǎn)) 和 DI(依賴注入)的概念,而 Spring Bean 就是 IoC 容器管理的“居民”。
5.Bean 的幾種定義方式
在 Spring的時代,我們主要用 XML 定義 Bean,現(xiàn)在注解和 Java Config 也很常見了,這里我把三種方式都給大家展示一下:
1)XML 配置(經(jīng)典老派)
圖片
你看,這就像是 Spring 容器的“戶口本”,我們把所有的對象都登記了,Spring 會幫我們創(chuàng)建并注入它們的依賴。
2)注解方式(現(xiàn)代主流)
圖片
圖片
加上 @Component、@Repository 等注解,Spring 會自動掃描包下的類,把它們注冊為 Bean。
3)Java Config 配置(注解控福音)
圖片
這種方式更靈活、可測試,也不依賴注解掃描,更受一些框架開發(fā)者的青睞。
6.Spring Bean 的生命周期
很多人理解 Spring Bean 只是“new 出來而已”,但其實它有一整個生命周期!
我面試時就順手畫了個圖在紙上,講給面試官看(字丑忽略):
- 實例化(Instantiation)
- 屬性注入(Populate properties)
- 感知接口調(diào)用(如 BeanNameAware、ApplicationContextAware)
- 初始化前處理(BeanPostProcessor#postProcessBeforeInitialization)
- 初始化方法(@PostConstruct 或 InitializingBean)
- 初始化后處理(BeanPostProcessor#postProcessAfterInitialization)
- 使用中
- 銷毀前處理(@PreDestroy 或 DisposableBean)
- 銷毀
是不是挺復雜?但大多數(shù)我們只關心幾個環(huán)節(jié):
- 創(chuàng)建時機(單例 or 多例)
- 注入時機(構(gòu)造器 or setter)
- 銷毀時機(有沒有釋放資源)
7.Bean 的作用域(Scope)
Spring 默認 Bean 是單例的(singleton),但它支持多種作用域:
圖片
設置方式:
圖片
8.Bean 的依賴注入方式
在面試中我還特別提到了一點:Bean 的依賴注入方式,這是體現(xiàn)設計思想的地方:
1)構(gòu)造器注入(推薦)
圖片
優(yōu)點是依賴不可變、強制依賴明確、便于測試。
2) Setter 注入(有些框架兼容性好)
圖片
適合可選依賴。
3) 字段注入(最簡單但不推薦)
圖片
對測試不友好,不易擴展。
9.Spring Bean 相關的常見注解
來個表格一鍵掌握:
圖片
10.小米的面試答題技巧
說實話,這種問題本身不難,但 面試中拼的不是你是否知道,而是你表達得是否有條理、有邏輯、有深度。
我一般會這樣回答:
- 一段定義:什么是 Spring Bean
- 兩種理解角度:
程序員視角:怎么用,怎么注入,怎么配置
- 容器視角:由誰創(chuàng)建,怎么管理,生命周期
- 三種配置方式:XML、注解、Java Config
- 補充點亮點:
- Spring 的發(fā)展歷程(這題太適合加點“版本”亮點)
- 依賴注入方式
- 作用域
- 生命周期
11.總結(jié)一下
如果你看到這里,小米想給你一個抱抱,因為你已經(jīng)遠遠超過很多浮躁的“看標題黨”程序員啦。
今天我們講了:
- 什么是 Spring Bean
- 為什么需要 Bean 管理
- 三種定義方式:XML、注解、Java Config
- 生命周期和作用域
- 依賴注入的三種方式
- 常見注解
- 面試答題的技巧和節(jié)奏
END
其實每一次的面試,都是一次整理自己認知的機會。別小看一個“老掉牙”的問題,它可能就是你和 offer 之間的那堵墻。
Spring 雖然有點老了,但它是我們無數(shù)人入門的起點。我們從“配置 Bean”開始,學會了依賴注入、IoC 的哲學思想,也慢慢走進了更深的架構(gòu)設計世界。