欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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í)例化之前,對 Bean 的配置元數(shù)據(jù)(即 BeanDefinition)進(jìn)行動(dòng)態(tài)修改或擴(kuò)展。其核心功能圍繞以下兩點(diǎn):

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

2. 核心功能詳解

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

3. 關(guān)鍵特性

  • 執(zhí)行時(shí)機(jī):在 BeanDefinition 加載完成之后、Bean 實(shí)例化之前(即 refresh() 方法中的 invokeBeanFactoryPostProcessors 階段)。
  • 作用對象:操作對象是 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 等注解,注冊相關(guān) BeanDefinition。
  • 實(shí)現(xiàn)接口:BeanDefinitionRegistryPostProcessor
  • 優(yōu)先級(jí):PriorityOrdered(最高)。
  • 源碼關(guān)鍵邏輯:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    processConfigBeanDefinitions(registry); // 掃描并注冊配置類中的 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 并注冊到容器。
  • 實(shí)現(xiàn)接口BeanFactoryPostProcessor
  • 觸發(fā)時(shí)機(jī)BeanFactoryPostProcessor 階段注冊監(jiān)聽器。

4. CustomScopeConfigurer

  • 作用:注冊自定義作用域(如 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. 注冊外部配置客戶端

public class ConfigClientPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 注冊遠(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. 典型場景示例

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

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

  • 擴(kuò)展性:通過組合模式而非繼承,靈活擴(kuò)展 Spring 容器。
  • 性能優(yōu)化:在 Bean 實(shí)例化前修改元數(shù)據(jù),避免重復(fù)初始化開銷。
  • 應(yīng)用場景:
    • 動(dòng)態(tài)配置:根據(jù)環(huán)境變量調(diào)整 Bean 屬性。
    • 插件化架構(gòu):運(yùn)行時(shí)注冊新組件(如數(shù)據(jù)庫驅(qū)動(dòng))。
    • AOP 前置處理:注冊代理相關(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java和Redis實(shí)現(xiàn)熱搜功能

    Java和Redis實(shí)現(xiàn)熱搜功能

    這篇文章主要介紹了Java和Redis實(shí)現(xiàn)熱搜功能,在存儲(chǔ)和傳輸用戶搜索數(shù)據(jù)時(shí),考慮到數(shù)據(jù)的機(jī)密性和隱私保護(hù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • spring-boot 禁用swagger的方法

    spring-boot 禁用swagger的方法

    本篇文章主要介紹了spring-boot 禁用swagger的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java LinkedList的實(shí)現(xiàn)原理圖文詳解

    Java LinkedList的實(shí)現(xiàn)原理圖文詳解

    今天小編就為大家分享一篇關(guān)于Java LinkedList的實(shí)現(xiàn)原理圖文詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 使用java文件過濾器輸出制定格式文件路徑的實(shí)例代碼

    使用java文件過濾器輸出制定格式文件路徑的實(shí)例代碼

    這篇文章主要介紹了使用java文件過濾器輸出制定格式文件路徑的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • ThreadPoolExecutor線程池原理及其execute方法(詳解)

    ThreadPoolExecutor線程池原理及其execute方法(詳解)

    下面小編就為大家?guī)硪黄猅hreadPoolExecutor線程池原理及其execute方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Spark?SQL配置及使用教程

    Spark?SQL配置及使用教程

    SparkSQL是spark的一個(gè)模塊,主入口是SparkSession,將SQL查詢與Spark程序無縫混合,這篇文章主要介紹了Spark?SQL配置及使用,需要的朋友可以參考下
    2021-12-12
  • Java?如何接收kernel傳過來的數(shù)組(推薦)

    Java?如何接收kernel傳過來的數(shù)組(推薦)

    這篇文章主要介紹了Java?如何接收kernel傳過來的數(shù)組,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-08-08
  • SpringBoot中Jackson日期格式化技巧分享

    SpringBoot中Jackson日期格式化技巧分享

    一般在SpringBoot項(xiàng)目中,spring默認(rèn)使用jackson轉(zhuǎn)換日期,下面這篇文章主要給大家介紹了關(guān)于SpringBoot中Jackson日期格式化技巧的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • springBoot service層事務(wù)控制的操作

    springBoot service層事務(wù)控制的操作

    這篇文章主要介紹了springBoot service層事務(wù)控制的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java8?CompletableFuture?異步多線程的實(shí)現(xiàn)

    Java8?CompletableFuture?異步多線程的實(shí)現(xiàn)

    本文主要介紹了Java8?CompletableFuture?異步多線程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評論