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

Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析

 更新時(shí)間:2025年03月18日 11:08:17   作者:xiaolingting  
Spring的BeanFactoryPostProcessor是容器初始化的擴(kuò)展接口,允許在Bean實(shí)例化前修改或擴(kuò)展Bean的配置元數(shù)據(jù),本文給大家介紹Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析,感興趣的朋友一起看看吧

一、概覽

1. 核心定位

BeanFactoryPostProcessor 是 Spring 容器級(jí)別的擴(kuò)展接口在 Bean 實(shí)例化之前,對(duì) Bean 的配置元數(shù)據(jù)(即 BeanDefinition)進(jìn)行動(dòng)態(tài)修改或擴(kuò)展。其核心功能圍繞以下兩點(diǎn):

  • 修改現(xiàn)有 Bean 的定義(如屬性值、作用域、初始化方法等)。
  • 添加新的 Bean 定義(需通過子接口 BeanDefinitionRegistryPostProcessor)。

2. 核心功能詳解

功能場(chǎng)景與示例
動(dòng)態(tài)調(diào)整 Bean 配置修改屬性值(如占位符替換)、調(diào)整作用域(單例改原型)、覆蓋懶加載設(shè)置等。
例:PropertySourcesPlaceholderConfigurer 解析 ${} 占位符。
注冊(cè)新 Bean 定義通過子接口 BeanDefinitionRegistryPostProcessor 動(dòng)態(tài)注冊(cè)新 Bean(如根據(jù)條件加載不同實(shí)現(xiàn)類)。
全局性配置處理批量修改所有 Bean 的公共屬性(如統(tǒng)一設(shè)置緩存超時(shí)時(shí)間)。
與外部配置集成結(jié)合環(huán)境變量或遠(yuǎn)程配置中心,動(dòng)態(tài)覆蓋 Bean 的初始配置(如數(shù)據(jù)庫(kù)連接參數(shù)動(dòng)態(tài)更新)。
擴(kuò)展容器能力注冊(cè)自定義作用域(如線程級(jí)別作用域)、實(shí)現(xiàn)模塊化配置加載(如插件化架構(gòu)中的模塊注冊(cè))。

3. 關(guān)鍵特性

  • 執(zhí)行時(shí)機(jī):在 BeanDefinition 加載完成之后、Bean 實(shí)例化之前(即 refresh() 方法中的 invokeBeanFactoryPostProcessors 階段)。
  • 作用對(duì)象:操作對(duì)象是 BeanDefinition(配置元數(shù)據(jù)),而非 Bean 實(shí)例,避免過早實(shí)例化導(dǎo)致性能問題。
  • 擴(kuò)展層級(jí)
    • 直接實(shí)現(xiàn)BeanFactoryPostProcessor 用于修改現(xiàn)有配置。
    • 子接口擴(kuò)展BeanDefinitionRegistryPostProcessor 支持新增/刪除 BeanDefinition,且執(zhí)行更早。
  • 執(zhí)行順序
    • 所有 BeanDefinitionRegistryPostProcessor(優(yōu)先處理 PriorityOrdered,再 Ordered,最后普通實(shí)現(xiàn))。
    • 所有 BeanFactoryPostProcessor(同上優(yōu)先級(jí)順序)。

二、Spring 內(nèi)置的 BeanFactoryPostProcessor

1. ConfigurationClassPostProcessor

  • 作用:解析 @Configuration 類、@ComponentScan、@Import 等注解,注冊(cè)相關(guān) BeanDefinition。
  • 實(shí)現(xiàn)接口:BeanDefinitionRegistryPostProcessor。
  • 優(yōu)先級(jí):PriorityOrdered(最高)。
  • 源碼關(guān)鍵邏輯:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    processConfigBeanDefinitions(registry); // 掃描并注冊(cè)配置類中的 Bean
}

2. PropertySourcesPlaceholderConfigurer

  • 作用:解析 BeanDefinition 中的占位符(如 ${jdbc.url}),替換為 Environment 中的實(shí)際值。
  • 實(shí)現(xiàn)接口BeanFactoryPostProcessor。
  • 源碼關(guān)鍵邏輯
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    processProperties(beanFactory); // 替換占位符
}

3. EventListenerMethodProcessor

  • 作用:掃描 @EventListener 注解,將方法包裝為 ApplicationListener 并注冊(cè)到容器。
  • 實(shí)現(xiàn)接口BeanFactoryPostProcessor。
  • 觸發(fā)時(shí)機(jī)BeanFactoryPostProcessor 階段注冊(cè)監(jiān)聽器。

4. CustomScopeConfigurer

  • 作用:注冊(cè)自定義作用域(如 requestsession)。
  • 實(shí)現(xiàn)接口BeanFactoryPostProcessor。
  • 示例
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.registerScope("thread", new SimpleThreadScope());
}

三、用戶自定義的 BeanFactoryPostProcessor

1. 動(dòng)態(tài)修改 BeanDefinition

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        BeanDefinition beanDef = beanFactory.getBeanDefinition("user");
        beanDef.getPropertyValues().add("name", "xiaolingting");
    }
}

2. 注冊(cè)外部配置客戶端

public class ConfigClientPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 注冊(cè)遠(yuǎn)程配置中心客戶端
        registry.registerBeanDefinition("configClient", new RootBeanDefinition(ConfigClient.class));
    }
}

四、執(zhí)行流程與源碼分析

1. 核心入口方法

AbstractApplicationContext#refresh() 中調(diào)用:

invokeBeanFactoryPostProcessors(beanFactory);

2. 處理順序邏輯

步驟 1:處理 BeanDefinitionRegistryPostProcessor 實(shí)現(xiàn)類:

// 獲取所有實(shí)現(xiàn)類并按優(yōu)先級(jí)排序
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class);
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    }
    // 其他優(yōu)先級(jí)處理...
}

步驟 2:處理 BeanFactoryPostProcessor 實(shí)現(xiàn)類:

// 按優(yōu)先級(jí)分組調(diào)用
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

3. 典型場(chǎng)景示例

  • 配置類掃描:ConfigurationClassPostProcessor 在 postProcessBeanDefinitionRegistry 階段掃描 @Component 并注冊(cè) Bean。
  • 占位符替換:PropertySourcesPlaceholderConfigurer 在 postProcessBeanFactory 階段替換屬性值。

五、設(shè)計(jì)意義與最佳實(shí)踐

  • 擴(kuò)展性:通過組合模式而非繼承,靈活擴(kuò)展 Spring 容器。
  • 性能優(yōu)化:在 Bean 實(shí)例化前修改元數(shù)據(jù),避免重復(fù)初始化開銷。
  • 應(yīng)用場(chǎng)景:
    • 動(dòng)態(tài)配置:根據(jù)環(huán)境變量調(diào)整 Bean 屬性。
    • 插件化架構(gòu):運(yùn)行時(shí)注冊(cè)新組件(如數(shù)據(jù)庫(kù)驅(qū)動(dòng))。
    • AOP 前置處理:注冊(cè)代理相關(guān)的 BeanPostProcessor。

總結(jié):Spring 的 BeanFactoryPostProcessor 是容器初始化的核心擴(kuò)展點(diǎn),通過內(nèi)置和自定義實(shí)現(xiàn),開發(fā)者可在不同階段精確控制 Bean 的元數(shù)據(jù)和行為,為復(fù)雜應(yīng)用提供強(qiáng)大的底層支持。

附:源碼

到此這篇關(guān)于Spring 中 BeanFactoryPostProcessor 的作用和示例的文章就介紹到這了,更多相關(guān)Spring BeanFactoryPostProcessor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot3 + Sa-Token 雙Token登錄認(rèn)證實(shí)戰(zhàn)案例解析

    SpringBoot3 + Sa-Token 雙Token登錄認(rèn)證實(shí)戰(zhàn)案例解析

    本文詳細(xì)介紹了如何在SpringBoot3項(xiàng)目中使用Sa-Token框架實(shí)現(xiàn)雙Token登錄認(rèn)證,全面展示了雙Token登錄認(rèn)證的實(shí)現(xiàn)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2026-02-02
  • java實(shí)現(xiàn)網(wǎng)頁(yè)驗(yàn)證碼功能

    java實(shí)現(xiàn)網(wǎng)頁(yè)驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)網(wǎng)頁(yè)驗(yàn)證碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • KotlinScript構(gòu)建SpringBootStarter保姆級(jí)教程

    KotlinScript構(gòu)建SpringBootStarter保姆級(jí)教程

    這篇文章主要為大家介紹了KotlinScript構(gòu)建SpringBootStarter的保姆級(jí)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • springboot如何初始化執(zhí)行sql語(yǔ)句

    springboot如何初始化執(zhí)行sql語(yǔ)句

    這篇文章主要介紹了springboot初始化執(zhí)行sql語(yǔ)句的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring整合Mybatis具體代碼實(shí)現(xiàn)流程

    Spring整合Mybatis具體代碼實(shí)現(xiàn)流程

    這篇文章主要介紹了Spring整合Mybatis實(shí)操分享,文章首先通過介紹Mybatis的工作原理展開Spring整合Mybatis的詳細(xì)內(nèi)容,需要的小伙伴可以參考一下
    2022-05-05
  • SpringBoot任務(wù)之定時(shí)任務(wù)相關(guān)知識(shí)總結(jié)

    SpringBoot任務(wù)之定時(shí)任務(wù)相關(guān)知識(shí)總結(jié)

    今天給大家整理的文章是SpringBoot定時(shí)任務(wù)的相關(guān)知識(shí)點(diǎn),文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)SpringBoot任務(wù)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼

    Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼

    Java中我們可以使用諸如JJWT這樣的庫(kù)來生成和驗(yàn)證JWT,本文主要介紹了Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • 淺談Java代碼的 微信長(zhǎng)鏈轉(zhuǎn)短鏈接口使用 post 請(qǐng)求封裝Json(實(shí)例)

    淺談Java代碼的 微信長(zhǎng)鏈轉(zhuǎn)短鏈接口使用 post 請(qǐng)求封裝Json(實(shí)例)

    下面小編就為大家?guī)硪黄獪\談Java代碼的 微信長(zhǎng)鏈轉(zhuǎn)短鏈接口使用 post 請(qǐng)求封裝Json(實(shí)例)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • Java Spring的數(shù)據(jù)庫(kù)開發(fā)詳解

    Java Spring的數(shù)據(jù)庫(kù)開發(fā)詳解

    這篇文章主要介紹了Spring的數(shù)據(jù)庫(kù)開發(fā),主要圍繞SpringJDBC和Spring Jdbc Template兩個(gè)技術(shù)來講解,文中有詳細(xì)的代碼示例,需要的小伙伴可以參考一下
    2023-04-04
  • 詳解SpringBoot配置連接池

    詳解SpringBoot配置連接池

    本篇文章主要詳解SpringBoot配置連接池,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04

最新評(píng)論

呼伦贝尔市| 鄂尔多斯市| 喜德县| 涞水县| 宁明县| 永登县| 普洱| 宿松县| 京山县| 略阳县| 岳西县| 天台县| 昌江| 修武县| 班戈县| 诏安县| 吴江市| 罗源县| 塔城市| 永善县| 阿巴嘎旗| 永丰县| 吴桥县| 会东县| 盐城市| 元朗区| 西华县| 红河县| 诸暨市| 苏尼特右旗| 赤峰市| 富阳市| 阳山县| 邳州市| 应城市| 拜城县| 商河县| 高青县| 武定县| 浦江县| 泸定县|