Spring Aware 到底是什麼?

tan日拱一兵發表於2019-07-19

Spring Aware 到底是什麼?

通過如下前序兩篇文章:

  1. Spring Bean 生命週期之“我從哪裡來”?
  2. Spring Bean 生命週期之“我要到哪裡去”?
    我們瞭解了 Spring Bean 的生命週期核心內容,bean 是如何被初始化變為 Ready for Use 的狀態,當資源被回收時又是如何被 destroy 的,但 Spring Bean Life Cycle圖並未被全部點亮,這篇文章將點亮剩餘內容,同時說說你常見的 XxxxAware 介面

為什麼要說 Spring Bean 生命週期又說 Aware 呢?下來點亮剩下內容你也許就明白了:

Spring Aware 到底是什麼?

  1. 在 Spring Bean Ready for Use之前的起源當然是要呼叫構造器,所以 Constructor 毋庸置疑是建立 Spring Bean 的第一步
  2. 通過 Setter 方法完成依賴注入,SDI (Setter Dependency Injection)
  3. 依賴注入一旦結束,BeanNameAware.setBeanName() 會被呼叫,它設定該 bean 在 Bean Factory 中的名稱
  4. 接下來呼叫 BeanClassLoaderAware.setBeanClassLoader(),為 bean 例項提供類載入器,我們知道所有類都是要通過類載入器載入到上下文的,關於類的載入機制/雙親委派模型(大廠都愛問的面試題)內容會在後續給出來,讓你透徹的瞭解
  5. 然後 BeanFactoryAware.setBeanFactory() 會被呼叫為 bean 例項提供其所擁有的 factory

關於 1、2 兩點我要額外多說一些內容,請看下面程式碼:
Spring Aware 到底是什麼?

這裡,我們嘗試通過構造器訪問自動注入的 field Environment env,當構造器被呼叫時,Spring Bean 還沒被完全初始化,這就會導致 NullPointerExceptions
我們變換一下方式:
Spring Aware 到底是什麼?

這種方式,Environment 例項被安全注入之後才呼叫 @PostConstruct標記的方法,這樣就不會丟擲 NullPointerException 了。

這會回看週期圖,有沒有豁然開朗?

敲黑板

等所有 Spring Bean 都完成依賴注入(週期圖中的 Setter Methods 部分)再使用 bean 的引用才是安全的方式,

後續會有一個章節專門說一說面試經常被問起的 Spring 有幾種依賴注入方式的尷尬問題,請關注後續文章

到這裡終於可以說一說 Aware 了,且看

Aware

Spring 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 獲取資源載入器,這樣獲取外部資原始檔

來看類關係圖:
Spring Aware 到底是什麼?

當然不止以上這些 Aware, 通常使用 Spring Aware 的目的是為了讓 Bean 獲得 Spring 容器的服務。

程式碼示例

BeanNameAware

自定義 bean 實現 BeanNameAware
Spring Aware 到底是什麼?

註冊 bean
Spring Aware 到底是什麼?

執行
Spring Aware 到底是什麼?

和預想一樣,Bean Name 輸出結果為 myCustomBeanName,如果移除掉 @Bean 註解的 name 屬性, 輸出結果為 getMyBeanName

總結

在大多數情況下,我們應該避免使用任何 Aware 介面,除非我們需要它們。實現這些介面會將程式碼耦合到Spring框架,但是希望看過本節內容之後閱讀框架原始碼思維更加清晰

靈魂追問

  1. 框架中有哪些經典的 Aware 應用?
  2. 到現在你能很好的理解 Spring Bean 的生命週期嗎?

Demo程式碼

涉及到 Spring Bean 生命週期的測試程式碼由於內容較多,沒有寫在此處,關注公眾號並回復 「demo」獲取相關程式碼,請自行嘗試執行結果


提高效率工具

Spring Aware 到底是什麼?


歡迎持續關注公眾號:「日拱一兵」

  • 前沿 Java 技術乾貨分享
  • 高效工具彙總
  • 面試問題分析與解答
  • 技術資料領取

後續會出一系列文章點亮上圖,同時進行 Spring 知識點解釋與串聯,在工作中充分利用 Spring 的特性
另外,還會推出 Java 多執行緒與 ElasticSearch 相關內容

持續關注,帶你像讀偵探小說一樣輕鬆趣味學習 Java 技術棧相關知識

Spring Aware 到底是什麼?

相關文章