Spring Aware 究竟是什麼?

經過以下前序兩篇文章:面試

  1. Spring Bean 生命週期之「我從哪裏來」?
  2. Spring Bean 生命週期之「我要到哪裏去」?

咱們瞭解了 Spring Bean 的生命週期核心內容,bean 是如何被初始化變爲 Ready for Use 的狀態,當資源被回收時又是如何被 destroy 的,但 Spring Bean Life Cycle圖並未被所有點亮,這篇文章將點亮剩餘內容,同時說說你常見的 XxxxAware 接口安全

爲何要說 Spring Bean 生命週期又說 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

關於 一、2 兩點我要額外多說一些內容,請看下面代碼:
框架

這裏,咱們嘗試經過構造器訪問自動注入的 field Environment env,當構造器被調用時,Spring Bean 還沒被徹底初始化,這就會致使 NullPointerExceptions
咱們變換一下方式:
工具

這種方式,Environment 實例被安全注入以後才調用 @PostConstruct標記的方法,這樣就不會拋出 NullPointerException 了。學習

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

敲黑板

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

後續會有一個章節專門說一說面試常常被問起的 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框架,可是但願看過本節內容以後閱讀框架源碼思惟更加清晰

靈魂追問

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

Demo代碼

涉及到 Spring Bean 生命週期的測試代碼因爲內容較多,沒有寫在此處,關注公衆號並回復 「demo」獲取相關代碼,請自行嘗試運行結果


提升效率工具

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

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

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

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

相關文章
相關標籤/搜索