通過如下前序兩篇文章:
Spring Bean Life Cycle
圖并未被全部點(diǎn)亮,這篇文章將點(diǎn)亮剩余內(nèi)容,同時(shí)說說你常見的 XxxxAware 接口為什么要說 Spring Bean 生命周期又說 Aware 呢?下來點(diǎn)亮剩下內(nèi)容你也許就明白了:
Ready for Use
之前的起源當(dāng)然是要調(diào)用構(gòu)造器,所以 Constructor 毋庸置疑是創(chuàng)建 Spring Bean 的第一步BeanNameAware.setBeanName()
會被調(diào)用,它設(shè)置該 bean 在 Bean Factory 中的名稱BeanClassLoaderAware.setBeanClassLoader()
,為 bean 實(shí)例提供類加載器,我們知道所有類都是要通過類加載器加載到上下文的,關(guān)于類的加載機(jī)制/雙親委派模型(大廠都愛問的面試題)內(nèi)容會在后續(xù)給出來,讓你透徹的了解BeanFactoryAware.setBeanFactory()
會被調(diào)用為 bean 實(shí)例提供其所擁有的 factory關(guān)于 1、2 兩點(diǎn)我要額外多說一些內(nèi)容,請看下面代碼:
這里,我們嘗試通過構(gòu)造器訪問自動注入的 fieldEnvironment env
,當(dāng)構(gòu)造器被調(diào)用時(shí),Spring Bean 還沒被完全初始化,這就會導(dǎo)致NullPointerExceptions
;
我們變換一下方式:
這種方式,Environment 實(shí)例被安全注入之后才調(diào)用@PostConstruct
標(biāo)記的方法,這樣就不會拋出NullPointerException
了。
這會回看周期圖,有沒有豁然開朗?
敲黑板
等所有 Spring Bean 都完成依賴注入(周期圖中的 Setter Methods 部分)再使用 bean 的引用才是安全的方式,
后續(xù)會有一個(gè)章節(jié)專門說一說面試經(jīng)常被問起的Spring 有幾種依賴注入方式
的尷尬問題,請關(guān)注后續(xù)文章
到這里終于可以說一說 Aware 了,且看
Aware 翻譯過來可以理解為"察覺的;注意到的;感知的" ,XxxxAware 也就是對....感知的,沒有 Aware 就是無感知的嗎?對嘍
Spring 的依賴注入大亮點(diǎn)就是所有的 Bean 對 Spring 容器的存在是沒有意識的,拿 [Spring Bean 生命周期之“我從哪里來”?]() 文章中“小學(xué)生入少先隊(duì)”為例子說明,小學(xué)生還是那個(gè)小學(xué)生,加入少先隊(duì)還是加入共青團(tuán)只不過規(guī)則不一樣罷了
但是在實(shí)際項(xiàng)目中,我們不可避免的要用到 Spring 容器本身提供的資源(難免要有事情需要少先隊(duì)組織的幫助),這時(shí)候要讓 Bean 主動意識到 Spring 容器的存在,才能調(diào)用 Spring 所提供的資源,這就是 Spring Aware. 其實(shí) Spring Aware 是 Spring 設(shè)計(jì)為框架內(nèi)部使用的,若使用了,你的 Bean 將會和 Spring 框架耦合,所以自己不單獨(dú)使用,但是在讀框架源碼時(shí)希望你不再模糊.
常見的 Spring Aware 接口
Aware子接口 | 描述 |
---|---|
BeanNameAware | 獲取容器中 Bean 的名稱 |
BeanFactoryAware | 獲取當(dāng)前 BeanFactory ,這樣可以調(diào)用容器的服務(wù) |
ApplicationContextAware | 同上,在BeanFactory 和 ApplicationContext 的區(qū)別 中已明確說明 |
MessageSourceAware | 獲取 Message Source 相關(guān)文本信息 |
ApplicationEventPublisherAware | 發(fā)布事件 |
ResourceLoaderAware | 獲取資源加載器,這樣獲取外部資源文件 |
來看類關(guān)系圖:
當(dāng)然不止以上這些 Aware, 通常使用 Spring Aware 的目的是為了讓 Bean 獲得 Spring 容器的服務(wù)。
自定義 bean 實(shí)現(xiàn) BeanNameAware
注冊 bean
運(yùn)行
和預(yù)想一樣,Bean Name 輸出結(jié)果為myCustomBeanName
,如果移除掉 @Bean 注解的 name 屬性, 輸出結(jié)果為getMyBeanName
在大多數(shù)情況下,我們應(yīng)該避免使用任何 Aware 接口,除非我們需要它們。實(shí)現(xiàn)這些接口會將代碼耦合到Spring框架,但是希望看過本節(jié)內(nèi)容之后閱讀框架源碼思維更加清晰
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。