自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

答讀者問:BeanFactoryPostProcessor 似乎失效了?

開發(fā) 前端
經(jīng)過上面分析,小伙伴們可以看到,通過 @Bean 注解定義的 Bean,我們?yōu)閷傩再x值是在方法內(nèi)部完成的,這些方法內(nèi)部的邏輯其實(shí)并未被解析到 BeanDefinition 中,顯然也沒有必要把方法內(nèi)部的邏輯解析到 BeanDefinition 上去,因此,通過 @Bean 注解定義的 Bean,如果屬性中使用了占位符,是無法通過 BeanFactoryPostProcessor 自動(dòng)解析的。

有小伙伴在學(xué)習(xí) Spring 源碼視頻的時(shí)候,看了松哥講的 BeanFactoryPostProcessor 的用法之后,提出了這樣一個(gè)問題:

圖片圖片

圖片圖片

我來跟大家補(bǔ)充一下這個(gè)問題的上下文:

我講了 BeanFactoryPostProcessor,分析了其原理,也講了具體的使用場景,一個(gè)典型的使用場景是我們?cè)?XML 中定義 Bean 的時(shí)候,如果 Bean 的屬性是使用了 properties 文件占位符如 ${db.username} 這種,那么在 BeanFactoryPostProcessor 階段,就會(huì)對(duì)這個(gè)占位符進(jìn)行處理,將其替換成真正的 value。然后我還順手給大家舉了一個(gè)例子,我在 XML 文件中定義 Bean 的時(shí)候,給 Bean 的某一個(gè)屬性設(shè)置 value 為 ^username,然后在 BeanFactoryPostProcessor 中,我將 ^username 改為某一個(gè)字符串。

小伙伴看了松哥講的內(nèi)容之后,也照著寫了一個(gè),就是上面圖片中的代碼,不同的是,他是將 XML 配置改為了 Java 代碼配置,結(jié)果發(fā)現(xiàn)屬性 hok 并未變?yōu)?nbsp;NB,因此有了上述問題。

我覺得這個(gè)問題問的很好,給了小伙伴們一個(gè)從其他方面理解 Spring 的機(jī)會(huì),這也是我前面一直強(qiáng)調(diào)的,這次的 Spring 視頻需要各位小伙伴一起發(fā)力,大家有關(guān)于 Spring 的任何問題都可以提,我負(fù)責(zé)通過源碼來回答你。

問題分析

這個(gè)問題的分析,得先從 BeanDefinition 開始。在講 BeanFactoryPostProcessor 之前,松哥已經(jīng)和小伙伴們分析過 BeanDefinition 了,無論我們是通過 Java 代碼還是通過 XML 文件定義的 Bean 對(duì)象,在解析稱為 Bean 對(duì)象之前,得先解析成為 BeanDefinition,BeanDefinition 則有不同的分類,對(duì)于 XML 文件定義的 Bean,最終解析為 GenericBeanDefinition,而通過 @Bean 注解定義的 Bean 則解析為 ConfigurationClassBeanDefinition。

但是這兩個(gè)的處理原理顯然是有差異的。

對(duì)于 XML 定義的 Bean 來說,很明顯 XML 中的所有屬性都要先解析到 BeanDefinition 中,包括我們?cè)?XML 中配置的 Bean 的各種屬性,這一步是在 Spring 容器 refresh 方法中構(gòu)建 BeanFactory 的時(shí)候完成的(obtainFreshBeanFactory 方法),這一步完成之后,在后面的步驟會(huì)去執(zhí)行容器中所有的 BeanFactoryPostProcessor(invokeBeanFactoryPostProcessors),此時(shí)就會(huì)把前面解析出來的 BeanDefinition 中帶有占位符的屬性給替換過來,最后在 refresh 方法中執(zhí)行 finishBeanFactoryInitialization 方法完成 Bean 的初始化。

按照上面這一套流程順序,占位符被解析成為正常字符串沒什么問題。

但是,如果是 @Bean 注解配置的 Bean,則會(huì)有所差異。

首先,@Bean 注解所標(biāo)記的方法要被解析為一個(gè) ConfigurationClassBeanDefinition,這個(gè)過程本身是通過 ConfigurationClassPostProcessor 來完成的,而 ConfigurationClassPostProcessor 本質(zhì)上其實(shí)就是一個(gè) BeanFactoryPostProcessor,換言之,@Bean 注解標(biāo)記的方法是在 BeanFactoryPostProcessor 中被解析為 ConfigurationClassBeanDefinition 的。ConfigurationClassBeanDefinition 這個(gè) BeanDefinition 主要用來記錄 @Bean 注解所標(biāo)記的方法所屬的對(duì)象、方法的名稱、方法對(duì)象、方法參數(shù)、注解的參數(shù)等等信息,把這些信息記錄下來,將來在初始化 Bean 的時(shí)候,通過反射執(zhí)行目標(biāo)方法就可以了,即方法里邊的內(nèi)容是什么,ConfigurationClassBeanDefinition 其實(shí)并不關(guān)心。

最后則是和 XML 一樣,在 finishBeanFactoryInitialization 方法中完成 Bean 的初始化。

經(jīng)過上面分析,小伙伴們可以看到,通過 @Bean 注解定義的 Bean,我們?yōu)閷傩再x值是在方法內(nèi)部完成的,這些方法內(nèi)部的邏輯其實(shí)并未被解析到 BeanDefinition 中,顯然也沒有必要把方法內(nèi)部的邏輯解析到 BeanDefinition 上去,因此,通過 @Bean 注解定義的 Bean,如果屬性中使用了占位符,是無法通過 BeanFactoryPostProcessor 自動(dòng)解析的。

好啦,現(xiàn)在小伙伴提出的問題大家伙都明白了吧?

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(guān)推薦

2012-02-24 10:28:32

2012-10-31 09:41:47

WAN優(yōu)化SSLHTTPS

2014-12-15 11:16:34

vCenter SRM

2010-05-28 15:47:16

雙絞線

2022-04-01 08:37:07

SpringAPI前端

2023-06-05 08:15:30

MySQLInnoDB

2011-08-05 11:06:33

VMware vSph虛擬化

2011-11-03 09:29:32

2011-03-14 14:40:28

VMware Work

2009-12-02 15:02:17

路由器怎么安裝

2016-12-12 14:55:01

AndroidAndroid Vie

2011-12-08 09:47:08

虛擬化應(yīng)用虛擬化

2013-02-18 09:22:48

虛擬化KVM

2024-08-07 13:40:00

2025-04-23 08:10:00

2014-10-13 10:41:48

安防布線

2021-06-01 10:49:22

線程池Java開發(fā)

2021-06-03 14:23:57

線程線程池JAVA

2011-10-10 09:45:34

網(wǎng)絡(luò)虛擬化虛擬化

2013-02-26 14:03:47

VMware WorkWindows 8
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)