最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

17-Spring高級容器初始化:BeanFactoryPostProcessor是什么呢

2023-06-18 18:30 作者:儒猿課堂  | 我要投稿

開篇


上一節(jié),我們看到了ApplicationContext對BeanFactory擴展的一些功能點,包括對SPEL語言的支持、添加屬性編輯器的注冊器、添加新的一批感知接口并忽略這些感知接口以及添加接口指定的依賴。


這一節(jié),我們接著上一節(jié)的分析繼續(xù)來看下ApplicationContext對初級容器BeanFactory的一些其他功能擴展點,主要為一下幾個部分:

1.看下空實現(xiàn)的工廠后處理方法,到底有哪些特別的含義和作用

2.接著來自定義實現(xiàn)下工廠后處理器方法,演示一把看下效果

3.接著再來看下BeanFactoryPostProcessor又是什么東西

4.并且我們也自定義實現(xiàn)下BeanFactoryPostProcessor,看下具體是怎么玩的


空實現(xiàn)的工廠后處理方法


我們接著分析之前的refresh方法,如下圖:

上一節(jié),我們已經(jīng)看到了方法prepareBeanFactory,接下來,我們從方法postProcessBeanFactory開始入手,到方法里面看下:

可以看到方法postProcessBeanFactory是一個空實現(xiàn),而且和我們之前看到的很多空實現(xiàn)方法一樣,方法postProcessBeanFactory也是由protected關(guān)鍵字修飾的,毫無疑問,該方法也是Spring提供給我們的一個擴展點。

那方法postProcessBeanFactory留給子類具體是要去實現(xiàn)什么樣的功能呢?通過方法的注釋我們可以知道,方法postProcessBeanFactory是Spring暴露給子類去修改容器beanFactory的。


那允許子類在什么時候修改beanFactory呢?可以看到在注釋中描述了修改的時機,也就是在所有的bean的BeanDefinition都注冊到BeanFactory中,但還沒有進(jìn)行實例化的時候進(jìn)行修改,什么意思呢?


我們前面花費了大量的篇幅,其實就是在講解Spring如何從xml中解析bean標(biāo)簽,然后將解析到的BeanDefinition注入到Spring容器中,這個過程頂多算是bean屬性信息的一個初始化。


而bean的實例化說白了就是創(chuàng)建一個bean對象,觸發(fā)實例化最常見的一個場景就是我們直接調(diào)用Spring容器的getBean方法,這個時候,Spring就會獲取容器中的BeanDefinition,利用BeanDefinition中的各種屬性和值去創(chuàng)建一個bean出來,這個過程就是bean的實例化。


所以,相當(dāng)于方法postProcessBeanFactory給了我們一個機會,在實例化bean之前修改bean的一些屬性信息,因為我們根據(jù)方法postProcessBeanFactory的參數(shù)beanFactory,就可以獲取到所有注冊的bean的信息了。


自定義空實現(xiàn)工廠后處理方法

接下來,我們可以來演示下在bean初始化之前,如何通過覆蓋方法postProcessBeanFactory來修改bean的信息:

可以看到,我們可以自己寫一個類MyClassPathXmlApplicationContext繼承了ClassPathXmlApplicationContext,然后重寫方法postProcessBeanFactory。

通過方法postProcessBeanFactory中的參數(shù)beanFactory,我們可以獲取到名稱為student的BeanDefinition,然后,我們可以在這里對BeanDefinition進(jìn)行定制化的修改。

相當(dāng)于bean在實例化之前,我們就偷偷的修改BeanDefinition的信息了,比如,我們這里修改bean的類型為非單例的BeanDefinition.SCOPE_PROTOTYPE。


然后,寫一個類來測試下:

可以看到,代碼中的其它的一切和之前一樣,只是將ClassPathXmlApplicationContext修改成了MyClassPathXmlApplicationContext,然后我們運行下方法,看下效果:

可以看到,果然在調(diào)用到refresh方法中的postProcessBeanFactory方法時,回調(diào)了子類MyClassPathXmlApplicationContext中覆蓋的postProcessBeanFactory方法。

當(dāng)然,我們可以打開我們的腦洞想下,既然在方法postProcessBeanFactory中都能獲取到beanFactory了,我們能做的事情當(dāng)然也不僅僅只是局限于修改BeanDefinition的信息,而是整個容器beanFactory級別的信息都可以修改了,這也是諸多第三方框架基于Spring開發(fā)時一個非常重要的擴展手段。


BeanFactoryPostProcessor是什么呢?

接下來,我們繼續(xù)往后看:

可以看到,接下來開始調(diào)用方法invokeBeanFactoryPostProcessors,我們到方法里面看下:

通過方法的注釋,我們可以知道是要實例化并且調(diào)用所有的BeanFactoryPostProcessor,那什么是BeanFactoryPostProcessor呢?


我們到BeanFactoryPostProcessor中看下:

可以看到,BeanFactoryPostProcessor中的方法和我們剛才看到的空實現(xiàn)方法postProcessBeanFactory幾乎是一模一樣的,目的也是一樣的,也就是給了我們一次機會,允許我們通過參數(shù)beanFactory去獲取相應(yīng)的BeanDefinition并修改相應(yīng)的信息。


自定義BeanFactoryPostProcessor


但是從使用方式上,和剛才空實現(xiàn)的postProcessBeanFactory方法稍微有些不同的,就是需要額外實現(xiàn)BeanFactoryPostProcessor接口。

同樣的,我們通過一個小案例來演示下如何使用:

可以看到,首先我們自定義一個類MyBeanFactoryPostProcessor并且實現(xiàn)接口BeanFactoryPostProcessor,和剛才一樣,可以在方法postProcessBeanFactory中,通過參數(shù)beanFactory在容器級別修改一些信息,比如我們這里修改名稱為“student”的BeanDefinition信息。

然后,我們需要將MyBeanFactoryPostProcessor配置在applicationContext.xml中:

可以看到,和我們之前的student對象一樣,同樣通過bean標(biāo)簽配置好了MyBeanFactoryPostProcessor類。

將MyBeanFactoryPostProcessor配置在xml之后,MyBeanFactoryPostProcessor會像普通的bean一樣注冊到Spring容器中,后面才可以從Spring容器中獲取并調(diào)用它里面的方法。


最后,我們寫一個類來測試一下,看下方法postProcessBeanFactory是否會執(zhí)行,如下所示:

可以看到,代碼和我們的最初的代碼沒有任何區(qū)別,我們運行下看下:

可以看到,果然Spring就運行了postProcessBeanFactory方法,打印出了我們想要的信息。


看到這里,大家可能心里會有一個疑惑,既然我們在refresh方法中就可以通過繼承空實現(xiàn)方法postProcessBeanFactory來修改beanFactory容器級別的信息,Spring為什么還要給我們提供接口BeanFactoryPostProcessor呢?


個人覺得,如果我們要修改beanFactory中的很多種信息,而且每種修改操作的邏輯都非常的復(fù)雜,這些邏輯勢必會耦合在一個方法中,這樣也不太好。

現(xiàn)在有了BeanFactoryPostProcessor接口之后,我們可以為每種修改操作分別創(chuàng)建一個類來實現(xiàn)接口BeanFactoryPostProcessor,這樣的話至少在代碼邏輯上是解耦的。


總結(jié)


好了,今天的知識點我們就講到這里了,我們來總結(jié)一下吧。


這一節(jié),我們主要了解了一下refresh方法中,空實現(xiàn)方法postProcessBeanFactory的作用,同時,我們也初步了解了一下工廠后處理BeanFactoryPostProcessor是什么。

很簡單,其實就是在所有bean實例化之前,為我們提供了一個可以修改容器中BeanDefinition的機會,下一節(jié),我們具體來看下Spring是如何執(zhí)行BeanFactoryPostProcessor中的方法的。


17-Spring高級容器初始化:BeanFactoryPostProcessor是什么呢的評論 (共 條)

分享到微博請遵守國家法律
怀集县| 巴青县| 乐安县| 大兴区| 武川县| 江孜县| 夏河县| 丹巴县| 马公市| 杭州市| 榆社县| 温宿县| 长春市| 眉山市| 聊城市| 逊克县| 南开区| 如皋市| 巨鹿县| 崇义县| 凌海市| 晋江市| 邮箱| 平安县| 商都县| 齐齐哈尔市| 包头市| 林州市| 伊宁市| 玛纳斯县| 佛教| 隆德县| 平安县| 龙岩市| 岐山县| 武平县| 石城县| 大理市| 邳州市| 洪江市| 澄城县|