最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

BeanDefinitionRegistryPostProcessor如何動(dòng)態(tài)注冊(cè)Bean到Spring

 更新時(shí)間:2022年03月24日 14:39:54   作者:chun_soft  
這篇文章主要介紹了BeanDefinitionRegistryPostProcessor如何動(dòng)態(tài)注冊(cè)Bean到Spring,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1、理論

一般如果想將類注冊(cè)到spring容器,讓spring來(lái)完成實(shí)例化,常用方式如下:

  • xml中通過(guò)bean節(jié)點(diǎn)來(lái)配置;
  • 使用@Service、@Controller、@Conponent等注解。

最近在研究通過(guò)Spring初始化時(shí)掃描自定義注解,查到了通過(guò)實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor獲取Bean,從而獲得自定義注解。

Spring支持我們通過(guò)代碼來(lái)將指定的類注冊(cè)到spring容器中。

Spring容器初始化時(shí),從資源中讀取到bean的相關(guān)定義后,保存在BeanDefinitionMap,在實(shí)例化bean的操作就是依據(jù)這些bean的定義來(lái)做的,而在實(shí)例化之前,Spring允許我們通過(guò)自定義擴(kuò)展來(lái)改變bean的定義,定義一旦變了,后面的實(shí)例也就變了,而beanFactory后置處理器,即BeanFactoryPostProcessor就是用來(lái)改變bean定義的。

通過(guò)invokeBeanFactoryPostProcessors方法用來(lái)找出所有beanFactory后置處理器,并且調(diào)用這些處理器來(lái)改變bean的定義。

BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor的實(shí)現(xiàn)類在其postProcessBeanFactory方法被調(diào)用時(shí),可以對(duì)bean的定義進(jìn)行控制,因此BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn)類一共要實(shí)現(xiàn)以下兩個(gè)方法:

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException

該方法的實(shí)現(xiàn)中,主要用來(lái)對(duì)bean定義做一些改變。

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException

該方法用來(lái)注冊(cè)更多的bean到spring容器中,詳細(xì)觀察入?yún)eanDefinitionRegistry接口,看看這個(gè)參數(shù)能帶給我們什么能力。

從BeanDefinitionRegistry可以看到,BeanDefinitionRegistry提供了豐富的方法來(lái)操作BeanDefinition,判斷、注冊(cè)、移除等方法都準(zhǔn)備好了,我們?cè)诰帉憄ostProcessBeanDefinitionRegistry方法的內(nèi)容時(shí),就能直接使用入?yún)egistry的這些方法來(lái)完成判斷和注冊(cè)、移除等操作。

org.springframework.context.support.AbstractApplicationContext#refresh中的invokeBeanFactoryPostProcessors(beanFactory);

用來(lái)找出所有beanFactory后置處理器,并且調(diào)用這些處理器來(lái)改變bean的定義。

invokeBeanFactoryPostProcessors(beanFactory)實(shí)際上是委托

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

方法處理的。

首先處理BeanFactoryPostProcessor中的內(nèi)容:

所有實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口的bean,其postProcessBeanDefinitionRegistry方法都會(huì)調(diào)用,然后再調(diào)用其postProcessBeanFactory方法,這樣一來(lái),我們?nèi)绻远x了BeanDefinitionRegistryPostProcessor接口的實(shí)現(xiàn)類,那么我們開(kāi)發(fā)的postProcessBeanDefinitionRegistry和postProcessBeanFactory方法都會(huì)被執(zhí)行一次;

boolean reiterate = true;
while (reiterate) {
    reiterate = false;
    //查出所有實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口的bean名稱
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        //前面的邏輯中,已經(jīng)對(duì)實(shí)現(xiàn)了PriorityOrdered和Ordered的bean都處理過(guò)了,因此通過(guò)processedBeans過(guò)濾,processedBeans中沒(méi)有的才會(huì)在此處理
        if (!processedBeans.contains(ppName)) {
            //根據(jù)名稱和類型獲取bean
            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
            //把已經(jīng)調(diào)用過(guò)postProcessBeanDefinitionRegistry方法的bean全部放在registryPostProcessors中
            registryPostProcessors.add(pp);
            //把已經(jīng)調(diào)用過(guò)postProcessBeanDefinitionRegistry方法的bean的名稱全部放在processedBeans中
            processedBeans.add(ppName);
            //執(zhí)行此bean的postProcessBeanDefinitionRegistry方法
            pp.postProcessBeanDefinitionRegistry(registry);
            //改變退出while的條件
            reiterate = true;
        }
    }
}
/registryPostProcessors中保存了所有執(zhí)行過(guò)postProcessBeanDefinitionRegistry方法的bean,
//現(xiàn)在再來(lái)執(zhí)行這些bean的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
//regularPostProcessors中保存的是所有入?yún)⒅袔?lái)的BeanFactoryPostProcessor實(shí)現(xiàn)類,并且這里面已經(jīng)剔除了BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn)類,現(xiàn)在要讓這些bean執(zhí)行postProcessBeanFactory方法

2、實(shí)戰(zhàn)代碼

public class AnnotationScannerConfigurer implements BeanDefinitionRegistryPostProcessor {
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
		// 創(chuàng)建一個(gè)bean的定義類的對(duì)象
		RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestServiceImpl.class);
		// 將Bean 的定義注冊(cè)到Spring環(huán)境
		beanDefinitionRegistry.registerBeanDefinition("testService", rootBeanDefinition);
	}
	
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
	  // bean的名字為key, bean的實(shí)例為value
		Map<String, Object> beanMap = configurableListableBeanFactory.getBeansWithAnnotation(AutoDiscoverClass.class);
		}

其實(shí)在實(shí)際使用過(guò)程中,Spring啟動(dòng)時(shí)掃描自定義注解,是通過(guò)BeanFactoryPostProcessor接口的postProcessBeanFactory方法

configurableListableBeanFactory.getBeansWithAnnotation(AutoDiscoverClass.class);

獲取每一個(gè)有自定義注解的Bean。

這種方法沒(méi)滿足我的實(shí)際需求。

總結(jié)下

BeanFactoryPostProcessor可以修改各個(gè)注冊(cè)的Bean,BeanDefinitionRegistryPostProcessor可以動(dòng)態(tài)將Bean注冊(cè)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用ShardingSphere-Proxy實(shí)現(xiàn)分表分庫(kù)

    使用ShardingSphere-Proxy實(shí)現(xiàn)分表分庫(kù)

    這篇文章介紹了使用ShardingSphere-Proxy實(shí)現(xiàn)分表分庫(kù)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • Java Bean與xml互相轉(zhuǎn)換的方法分析

    Java Bean與xml互相轉(zhuǎn)換的方法分析

    這篇文章主要介紹了Java Bean與xml互相轉(zhuǎn)換的方法,結(jié)合實(shí)例形式分析了java bean與xml轉(zhuǎn)換的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2018-12-12
  • java安全?ysoserial?CommonsCollections1示例解析

    java安全?ysoserial?CommonsCollections1示例解析

    這篇文章主要介紹了java安全?ysoserial?CommonsCollections1示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用

    如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用

    這篇文章主要介紹了如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Java實(shí)現(xiàn)PDF轉(zhuǎn)HTML/Word/Excel/PPT/PNG的示例代碼

    Java實(shí)現(xiàn)PDF轉(zhuǎn)HTML/Word/Excel/PPT/PNG的示例代碼

    這篇文章主要為大家介紹了如何利用Java語(yǔ)言是PDF轉(zhuǎn)HTML、Word、Excel、PPT和PNG功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-05-05
  • Java實(shí)現(xiàn)獲取Excel中的表單控件

    Java實(shí)現(xiàn)獲取Excel中的表單控件

    Excel中可通過(guò)【開(kāi)發(fā)工具】菜單欄下插入表單控件,如文本框、單選按鈕、復(fù)選框、組合框等等。本文將利用Java實(shí)現(xiàn)獲取Excel中的表單控件,需要的可以參考一下
    2022-05-05
  • Java 添加、替換、刪除PDF中的圖片的示例代碼

    Java 添加、替換、刪除PDF中的圖片的示例代碼

    這篇文章主要介紹了Java 添加、替換、刪除PDF中的圖片,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • java生成圖片驗(yàn)證碼返回base64圖片信息方式

    java生成圖片驗(yàn)證碼返回base64圖片信息方式

    這篇文章主要介紹了java生成圖片驗(yàn)證碼返回base64圖片信息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • IDEA 2021.2 激活教程及啟動(dòng)報(bào)錯(cuò)問(wèn)題解決方法

    IDEA 2021.2 激活教程及啟動(dòng)報(bào)錯(cuò)問(wèn)題解決方法

    這篇文章主要介紹了IDEA 2021.2 啟動(dòng)報(bào)錯(cuò)及激活教程,文章開(kāi)頭給大家介紹了idea2021最新激活方法,關(guān)于idea2021啟動(dòng)報(bào)錯(cuò)的問(wèn)題小編也給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式

    SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式

    本文介紹了如何在Spring Boot 3中整合GraalVM,并將其打包為可執(zhí)行文件,適用于Windows和Linux系統(tǒng),通過(guò)安裝GraalVM、配置環(huán)境變量、下載Visual Studio組件(僅限Windows)以及使用Maven容器(適用于Linux),可以實(shí)現(xiàn)高效的打包和運(yùn)行
    2024-12-12

最新評(píng)論

文成县| 永兴县| 萨嘎县| 陆河县| 芦山县| 松滋市| 洞口县| 睢宁县| 青海省| 河间市| 泰兴市| 长沙市| 安庆市| 奉节县| 大埔县| 浮山县| 德格县| 台中县| 东城区| 东港市| 拜城县| 墨玉县| 康保县| 贵德县| 涿州市| 高青县| 肃北| 怀安县| 灌南县| 呼伦贝尔市| 临西县| 秦皇岛市| 寿光市| 德州市| 武川县| 博兴县| 濮阳市| 克拉玛依市| 酒泉市| 罗源县| 丹江口市|