日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
答讀者問:BeanFactoryPostProcessor似乎失效了?

有小伙伴在學習 Spring 源碼視頻的時候,看了松哥講的 BeanFactoryPostProcessor 的用法之后,提出了這樣一個問題:

為崇義等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及崇義網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為做網(wǎng)站、網(wǎng)站制作、崇義網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

圖片

圖片

我來跟大家補充一下這個問題的上下文:

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

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

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

問題分析

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

但是這兩個的處理原理顯然是有差異的。

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

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

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

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

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

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

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


名稱欄目:答讀者問:BeanFactoryPostProcessor似乎失效了?
文章轉(zhuǎn)載:http://www.5511xx.com/article/dpphhch.html