通過如下前序兩篇文章:
- Spring Bean 生命週期之“我從哪裡來”?
- Spring Bean 生命週期之“我要到哪裡去”?
我們瞭解了 Spring Bean 的生命週期核心內容,bean 是如何被初始化變為Ready for Use
的狀態,當資源被回收時又是如何被 destroy 的,但Spring Bean Life Cycle
圖並未被全部點亮,這篇文章將點亮剩餘內容,同時說說你常見的 XxxxAware 介面
為什麼要說 Spring Bean 生命週期又說 Aware 呢?下來點亮剩下內容你也許就明白了:
- 在 Spring Bean
Ready for Use
之前的起源當然是要呼叫構造器,所以 Constructor 毋庸置疑是建立 Spring Bean 的第一步 - 通過 Setter 方法完成依賴注入,SDI (Setter Dependency Injection)
- 依賴注入一旦結束,
BeanNameAware.setBeanName()
會被呼叫,它設定該 bean 在 Bean Factory 中的名稱 - 接下來呼叫
BeanClassLoaderAware.setBeanClassLoader()
,為 bean 例項提供類載入器,我們知道所有類都是要通過類載入器載入到上下文的,關於類的載入機制/雙親委派模型(大廠都愛問的面試題)內容會在後續給出來,讓你透徹的瞭解 - 然後
BeanFactoryAware.setBeanFactory()
會被呼叫為 bean 例項提供其所擁有的 factory
關於 1、2 兩點我要額外多說一些內容,請看下面程式碼:
這裡,我們嘗試通過構造器訪問自動注入的 field Environment env
,當構造器被呼叫時,Spring Bean 還沒被完全初始化,這就會導致 NullPointerExceptions
;
我們變換一下方式:
這種方式,Environment 例項被安全注入之後才呼叫 @PostConstruct
標記的方法,這樣就不會丟擲 NullPointerException
了。
這會回看週期圖,有沒有豁然開朗?
敲黑板
等所有 Spring Bean 都完成依賴注入(週期圖中的 Setter Methods 部分)再使用 bean 的引用才是安全的方式,
後續會有一個章節專門說一說面試經常被問起的 Spring 有幾種依賴注入方式
的尷尬問題,請關注後續文章
到這裡終於可以說一說 Aware 了,且看
Aware
Aware 翻譯過來可以理解為"察覺的;注意到的;感知的" ,XxxxAware 也就是對....感知的,沒有 Aware 就是無感知的嗎?對嘍
Spring 的依賴注入最大亮點就是所有的 Bean 對 Spring 容器的存在是沒有意識的,拿 Spring Bean 生命週期之“我從哪裡來”? 文章中“小學生入少先隊”為例子說明,小學生還是那個小學生,加入少先隊還是加入共青團只不過規則不一樣罷了
但是在實際專案中,我們不可避免的要用到 Spring 容器本身提供的資源(難免要有事情需要少先隊組織的幫助),這時候要讓 Bean 主動意識到 Spring 容器的存在,才能呼叫 Spring 所提供的資源,這就是 Spring Aware. 其實 Spring Aware 是 Spring 設計為框架內部使用的,若使用了,你的 Bean 將會和 Spring 框架耦合,所以自己不單獨使用,但是在讀框架原始碼時希望你不再模糊.
常見的 Spring Aware 介面
Aware子介面 | 描述 |
---|---|
BeanNameAware | 獲取容器中 Bean 的名稱 |
BeanFactoryAware | 獲取當前 BeanFactory ,這樣可以呼叫容器的服務 |
ApplicationContextAware | 同上,在BeanFactory 和 ApplicationContext 的區別 中已明確說明 |
MessageSourceAware | 獲取 Message Source 相關文字資訊 |
ApplicationEventPublisherAware | 釋出事件 |
ResourceLoaderAware | 獲取資源載入器,這樣獲取外部資原始檔 |
來看類關係圖:
當然不止以上這些 Aware, 通常使用 Spring Aware 的目的是為了讓 Bean 獲得 Spring 容器的服務。
程式碼示例
BeanNameAware
自定義 bean 實現 BeanNameAware
註冊 bean
執行
和預想一樣,Bean Name 輸出結果為 myCustomBeanName
,如果移除掉 @Bean 註解的 name 屬性, 輸出結果為 getMyBeanName
總結
在大多數情況下,我們應該避免使用任何 Aware 介面,除非我們需要它們。實現這些介面會將程式碼耦合到Spring框架,但是希望看過本節內容之後閱讀框架原始碼思維更加清晰
靈魂追問
- 框架中有哪些經典的 Aware 應用?
- 到現在你能很好的理解 Spring Bean 的生命週期嗎?
Demo程式碼
涉及到 Spring Bean 生命週期的測試程式碼由於內容較多,沒有寫在此處,關注公眾號並回復 「demo」獲取相關程式碼,請自行嘗試執行結果
提高效率工具
歡迎持續關注公眾號:「日拱一兵」
- 前沿 Java 技術乾貨分享
- 高效工具彙總
- 面試問題分析與解答
- 技術資料領取
後續會出一系列文章點亮上圖,同時進行 Spring 知識點解釋與串聯,在工作中充分利用 Spring 的特性
另外,還會推出 Java 多執行緒與 ElasticSearch 相關內容
持續關注,帶你像讀偵探小說一樣輕鬆趣味學習 Java 技術棧相關知識