摘要:代碼示例自定義實現注冊運行和預想一樣,輸出結果為,如果移除掉注解的屬性,輸出結果為總結在大多數情況下,我們應該避免使用任何接口,除非我們需要它們。
通過如下前序兩篇文章:
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 了,且看
AwareAware 翻譯過來可以理解為"察覺的;注意到的;感知的" ,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 技術棧相關知識
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75486.html
摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網。主要的功能是日志記錄,性能統計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...
摘要:容器管理的一般不需要了解容器的狀態和直接使用容器但是在某些情況下是需要在中直接對容器進行操作的可以通過特定的接口來完成接口有以下這些接口名描述實現了這個接口的類都可以獲取到一個對象可以獲取容器中的所有在中可以得到應用上下文的事件發布器從而可 容器管理的 Bean 一般不需要了解容器的狀態和直接使用容器, 但是在某些情況下, 是需要在 Bean 中直接對IOC容器進行操作的, 可以通過特...
摘要:也是屬于方法調用棧的一環,進去有類似一段偽代碼這段代碼通過遍歷得到所有的,然后挨個執行重寫的方法,倘若有一個方法返回的為,那么循環就會跳出,意味著下面的方法不會被執行。 Spring源碼原理篇--容器初始化&Bean后置處理器 本篇主要是講解IOC容器初始化過程中大體進行了哪一些工作,以及Bean后置處理器的工作原理和BeanPostProcessor在底層的使用。 環境準備 編譯器...
摘要:即,的后置處理器,它的作用就是在的初始化方法前跟后進行攔截處理。如何注冊后置處理器我們暫不作分析,著重說一下,后置處理器是如何工作的。 BeanPostProcessor即,Bean的后置處理器,它的作用就是在Bean的初始化方法前跟后進行攔截處理。我們都知道,要想在Bean的初始化方法前后進行工作,那必須在Bean實例創建完成之后,init方法執行之前,后置處理器就已經在容器中了,所...
摘要:創建及準備創建。目前已知關心這個事件的有要注意的是在這個階段,里只有,是的加載工作的起點。原因是注入這些回調接口本身沒有什么意義。在其構造函數內部間接的給注冊了幾個與相關注解的處理器。 相關代碼在: https://github.com/chanjarster/spring-boot-all-callbacks 注:本文基于spring-boot 1.4.1.RELEASE, spri...
閱讀 1578·2021-10-14 09:42
閱讀 3818·2021-09-07 09:59
閱讀 1302·2019-08-30 15:55
閱讀 575·2019-08-30 11:17
閱讀 3341·2019-08-29 16:06
閱讀 504·2019-08-29 14:06
閱讀 3130·2019-08-28 18:14
閱讀 3649·2019-08-26 13:55