Spring boot 加载和注册 BeanDefinition (三)

上一篇讲到Spring boot的常见容器,大部分Spring boot运用都没有启用AOT模式,现在看一下没有启用AOT模式的条件下如何加载和注册Spring 内部的 BeanDefinition,主配置类的加载和注册已经在这篇提到


1、BeanDefinitionRegistry接口

作用

BeanDefinitionRegistry 是 Spring 框架中用于管理 Bean 定义(BeanDefinition) 的核心接口,其作用是提供对 Bean 定义的注册、查询、删除等操作。它是 Spring IOC 容器构建过程中非常关键的一环。

核心方法

/**
 * 在此注册表中注册一个新的 Bean 定义。
 * 必须支持 RootBeanDefinition 和 ChildBeanDefinition 类型。
 *
 * @param beanName 要注册的 Bean 实例的名称
 * @param beanDefinition 要注册的 Bean 的定义信息
 * @throws BeanDefinitionStoreException 如果 Bean 定义无效,抛出此异常
 * @throws BeanDefinitionOverrideException 如果已经存在相同名称的 Bean 定义,
 * 并且不允许覆盖,则抛出此异常
 *
 * @see GenericBeanDefinition
 * @see RootBeanDefinition
 * @see ChildBeanDefinition
 */
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException;

常见实现类

实现类 描述
DefaultListableBeanFactory 标准的 BeanFactory 实现,内部维护完整的 Bean 定义集合,支持注册、查找和依赖注入
GenericApplicationContext 通用应用上下文实现,封装了 BeanFactory 和环境配置,包含DefaultListableBeanFactory

2、GenericApplicationContext容器

作用

GenericApplicationContext 是 Spring 框架中一个通用的、可编程的应用上下文实现类,位于 org.springframework.context.support 包中。它的主要作用是提供一个轻量级的容器环境,用于注册和管理 Bean 定义,并支持通过不同的配置方式(如 XML、Java 注解、Properties 等)加载 Bean。


源码

private final DefaultListableBeanFactory beanFactory;

/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

说明

BeanDefinition 最终使用DefaultListableBeanFactory注册

常见实现类(Spring boot容器)

实现类 描述
AnnotationConfigApplicationContext 使用注解驱动,依赖运行时反射
AnnotationConfigServletWebServerApplicationContext 使用注解驱动,支持 Web 应用,依赖运行时反射
AnnotationConfigReactiveWebServerApplicationContext 使用注解驱动,支持响应式 Web,依赖运行时反射

3、Spring boot容器

常见Spring boot创建的容器都会继承GenericApplicationContext,这使得容器本身也是BeanDefinitionRegistry,容器最终注册的BeanDefinition 都是到DefaultListableBeanFactory


4、AnnotatedBeanDefinitionReader

创建

在容器的构造函数中创建

this.reader = new AnnotatedBeanDefinitionReader(this);

说明

  • this就是容器,容器当作了BeanDefinitionRegistry

源码,核心方法是AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)

/**
 * 为给定的注册表创建一个新的 AnnotatedBeanDefinitionReader。
 *
 * 

如果该注册表实现了 {@link EnvironmentCapable} 接口(例如一个应用上下文), * 则会继承其环境配置;否则将创建并使用一个新的 {@link StandardEnvironment} 环境对象。 * * @param registry 要加载 Bean 定义的目标 BeanFactory,以 {@code BeanDefinitionRegistry} 的形式提供 * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) * @see #setEnvironment(Environment) */ public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } /** * 使用指定的环境配置,为给定的注册表创建一个新的 AnnotatedBeanDefinitionReader。 * * @param registry 要加载 Bean 定义的目标 BeanFactory,以 {@code BeanDefinitionRegistry} 的形式提供 * @param environment 在评估 Bean 定义配置文件(profile)时使用的环境对象 * @since 3.1 */ public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry 必须不为空"); Assert.notNull(environment, "Environment 必须不为空"); this.registry = registry; // 创建条件评估器,用于处理 @Conditional 注解等逻辑 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); // 注册 Spring 内部用于处理注解配置的处理器(如 ConfigurationClassPostProcessor) AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }

说明

  • AnnotatedBeanDefinitionReader构造函数中的registry就是容器本身
  • AnnotatedBeanDefinitionReader注册的BeanDefinition 放到容器中

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)方法,核心是注册 ConfigurationClassPostProcessor

/**
 * 在给定的注册表中注册所有相关的注解后处理器(Annotation Post Processors)。
 *
 * @param registry 要操作的 BeanDefinitionRegistry 注册表
 */
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
}

/**
 * 在给定的注册表中注册所有相关的注解后处理器。
 *
 * @param registry 要操作的 BeanDefinitionRegistry 注册表
 * @param source 触发此次注册的配置源对象(可为 null)
 * @return 返回一个包含所有实际注册的 Bean 定义的 Set 集合
 */
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, @Nullable Object source) {

    // 尝试获取底层使用的 DefaultListableBeanFactory 实例
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        // 如果依赖排序器不是 AnnotationAwareOrderComparator,则设置它
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }

        // 如果自动装配候选解析器不是 ContextAnnotationAutowireCandidateResolver,则设置默认的
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    // 创建用于存储已注册 Bean 定义的集合
    Set<BeanDefinitionHolder> beanDefs = CollectionUtils.newLinkedHashSet(6);

    // 注册 ConfigurationClassPostProcessor,用于处理 @Configuration 类
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册 AutowiredAnnotationBeanPostProcessor,用于处理 @Autowired、@Value 等注解
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否引入了 Jakarta 注解支持,如果存在则注册 CommonAnnotationBeanPostProcessor
    // 用于处理 @Resource、@PostConstruct、@PreDestroy 等注解
    if (jakartaAnnotationsPresent && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否引入了 JPA 支持,如果存在则注册 PersistenceAnnotationBeanPostProcessor
    // 用于处理 JPA 相关注解如 @PersistenceContext、@PersistenceUnit
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                    AnnotationConfigUtils.class.getClassLoader()));
        } catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "无法加载可选框架类: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册 EventListenerMethodProcessor,用于处理 @EventListener 注解
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    // 注册 DefaultEventListenerFactory,用于创建监听事件的工厂类
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
}

说明

  • registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)

    • 是一个简化版本,内部调用另一个重载方法,并传入 null 作为配置源。
  • registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source)

    • 注册 Spring 内部常用的一系列注解后处理器(BeanPostProcessor 和 BeanFactoryPostProcessor),以支持各种注解驱动的功能。

✅ 注册的主要后处理器及其作用

后处理器 对应注解/功能 说明
ConfigurationClassPostProcessor @Configuration, @ComponentScan, @Import 处理基于 Java 配置类的 Bean 定义
AutowiredAnnotationBeanPostProcessor @Autowired, @Value 处理自动注入逻辑
CommonAnnotationBeanPostProcessor @Resource, @PostConstruct, @PreDestroy 处理 Jakarta EE 标准注解
PersistenceAnnotationBeanPostProcessor @PersistenceContext, @PersistenceUnit 支持 JPA 注解处理
EventListenerMethodProcessor @EventListener 注册监听方法为 ApplicationListener
DefaultEventListenerFactory N/A 工厂类,用于创建事件监听器

小结

Spring boot创建容器的时候就已经注册一堆后处理器,这些后处理器将在AbstractApplicationContext.refresh()起作用


5、容器的refresh

1.SpringApplication.run() 方法,核心是refreshContext(context)方法

/**
 * 运行 Spring 应用程序,创建并刷新一个新的 {@link ApplicationContext}(应用上下文)。
 *
 * 该方法会执行以下主要步骤:
 * 1. 创建启动策略(Startup)实例;
 * 2. 注册关闭钩子(如果启用);
 * 3. 准备引导上下文(BootstrapContext);
 * 4. 配置 headless 属性;
 * 5. 获取运行监听器并通知 starting 事件;
 * 6. 准备环境配置(Environment);
 * 7. 打印 Banner;
 * 8. 创建应用上下文;
 * 9. 准备上下文环境;
 * 10. 刷新上下文;
 * 11. 调用 ApplicationRunner 和 CommandLineRunner;
 * 12. 处理异常和失败情况;
 * 13. 最后通知 listeners 应用已就绪。
 *
 * @param args 应用程序参数(通常由 main 方法传入)
 * @return 已经运行的 {@link ConfigurableApplicationContext}
 */
public ConfigurableApplicationContext run(String... args) {
    // 创建启动策略(用于处理启动指标)
    Startup startup = Startup.create();
    
    // 如果启用了注册关闭钩子,则启用它
    if (this.properties.isRegisterShutdownHook()) {
        SpringApplication.shutdownHook.enableShutdownHookAddition();
    }

    // 创建默认的 Bootstrap 上下文
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();

    // 初始化可配置的应用上下文为 null
    ConfigurableApplicationContext context = null;

    // 配置 headless 模式(默认为 true)
    configureHeadlessProperty();

    // 获取运行监听器并触发 starting 事件
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);

    try {
        // 封装应用程序参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

        // 准备环境配置(包括系统环境、JVM 参数等)
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);

        // 打印 Banner(控制台或日志)
        Banner printedBanner = printBanner(environment);

        // 创建应用上下文(根据 WebApplicationType 决定类型)
        context = createApplicationContext();

        // 设置应用启动监控
        context.setApplicationStartup(this.applicationStartup);

        // 准备应用上下文环境(设置 BeanFactoryPostProcessors、ResourceLoader 等)
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

        // 刷新上下文(加载 Bean 定义、初始化单例 Bean)
        refreshContext(context);

        // 刷新后处理(子类扩展点)
        afterRefresh(context, applicationArguments);

        // 记录启动耗时
        startup.started();

        // 如果启用了启动日志,记录启动完成信息
        if (this.properties.isLogStartupInfo()) {
            new StartupInfoLogger(this.mainApplicationClass, environment).logStarted(getApplicationLog(), startup);
        }

        // 通知监听器上下文已启动
        listeners.started(context, startup.timeTakenToStarted());
        
        // 调用所有 ApplicationRunner 和 CommandLineRunner
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        // 处理运行时异常
        throw handleRunFailure(context, ex, listeners);
    }

    try {
        // 如果上下文正在运行,通知监听器应用已准备就绪
        if (context.isRunning()) {
            listeners.ready(context, startup.ready());
        }
    }
    catch (Throwable ex) {
        // 处理就绪阶段的异常
        throw handleRunFailure(context, ex, null);
    }

    // 返回运行中的上下文
    return context;
}

说明

  • createApplicationContext()

    • 创建容器的时候就已经注册一堆Spring 内部的后处理器,特别是注册 ConfigurationClassPostProcessor
  • prepareContext(...)

    • 注册主配置类。
  • 内部的后处理器主配置类 将在 refreshContext(context) 起作用

2.SpringApplication.refreshContext() 方法

private void refreshContext(ConfigurableApplicationContext context) {
	if (this.properties.isRegisterShutdownHook()) {
		shutdownHook.registerApplicationContext(context);
	}
	refresh(context);
}

/**
* Refresh the underlying {@link ApplicationContext}.
* @param applicationContext the application context to refresh
*/
protected void refresh(ConfigurableApplicationContext applicationContext) {
	applicationContext.refresh();
}

说明

  • applicationContext.refresh() 最终调用的是 AbstractApplicationContext.refresh()

3.AbstractApplicationContext.refresh() 方法,核心是invokeBeanFactoryPostProcessors(beanFactory)

/**
 * 刷新此应用程序上下文,包括 BeanFactory 的创建、配置、刷新以及相关组件的初始化。
 * 此方法会加载所有单例 bean 并发布相应的事件。
 *
 * @throws BeansException 如果在初始化过程中发生 bean 相关错误
 * @throws IllegalStateException 如果上下文状态不正确(例如已关闭)
 */
public void refresh() throws BeansException, IllegalStateException {
    // 加锁以确保线程安全地执行刷新操作
    this.startupShutdownLock.lock();
    try {
        // 记录当前线程为启动/关闭线程
        this.startupShutdownThread = Thread.currentThread();

        // 启动应用启动性能追踪步骤
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // 1. 准备刷新:设置启动时间、激活标志、验证环境属性等
        prepareRefresh();

        // 2. 获取或刷新内部的 BeanFactory 实例(由子类实现)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 3. 对 BeanFactory 进行基本配置,如类加载器、表达式解析器、注册一些基础的后处理器等
        prepareBeanFactory(beanFactory);

        try {
            // 4. 允许子类对 BeanFactory 做进一步的定制化处理(模板方法)
            postProcessBeanFactory(beanFactory);

            // 启动 Bean 后处理器相关的性能追踪步骤
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

            // 5. 调用所有已注册的 BeanFactoryPostProcessor 来修改 BeanFactory 配置
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 注册 BeanPostProcessor,用于拦截 bean 的创建过程
            registerBeanPostProcessors(beanFactory);

            // 结束 Bean 后处理器的性能追踪步骤
            beanPostProcess.end();

            // 7. 初始化消息源(MessageSource),用于国际化支持
            initMessageSource();

            // 8. 初始化事件广播器(ApplicationEventMulticaster),用于事件发布
            initApplicationEventMulticaster();

            // 9. 模板方法,允许子类初始化特定上下文中的其他特殊 bean
            onRefresh();

            // 10. 注册监听器,包括静态监听器和 Bean 类型的监听器
            registerListeners();

            // 11. 完成 BeanFactory 的初始化,实例化所有非懒加载的单例 bean
            finishBeanFactoryInitialization(beanFactory);

            // 12. 完成刷新,重置缓存、发布 ContextRefreshedEvent 事件
            finishRefresh();
        }

        catch (RuntimeException | Error ex) {
            // 异常处理:记录日志、销毁已创建的单例、取消刷新、抛出异常
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // 销毁已创建的单例,避免资源泄漏
            destroyBeans();

            // 重置 active 标志
            cancelRefresh(ex);

            // 抛出异常给调用者
            throw ex;
        }

        finally {
            // 结束上下文刷新的性能追踪步骤
            contextRefresh.end();
        }
    }
    finally {
        // 清理启动/关闭线程引用,并释放锁
        this.startupShutdownThread = null;
        this.startupShutdownLock.unlock();
    }
}

说明:

  1. 准备阶段

    • 设置上下文的启动时间、激活状态;
    • 验证环境变量;
    • 初始化早期事件监听器和事件集合。
  2. BeanFactory 创建与配置

    • obtainFreshBeanFactory() 方法:子类负责创建一个新的 beanFactory,这里的子类是 GenericApplicationContextbeanFactory自然就是DefaultListableBeanFactory
    • 配置 ClassLoader、表达式解析器、资源编辑器等;
    • 注册一些基础的 BeanPostProcessor 和依赖解析策略。
  3. BeanFactory 后处理

    • 执行 BeanFactoryPostProcessor
    • 注册 BeanPostProcessor
    • 初始化消息源、事件广播器、生命周期处理器等核心组件。
  4. Bean 实例化

    • 注册监听器;
    • 实例化所有非懒加载的单例 bean。
  5. 完成刷新

    • 发布 ContextRefreshedEvent 事件;
    • 重置缓存;
    • 清理临时数据。

4.AbstractApplicationContext.invokeBeanFactoryPostProcessors(...) 方法,核心是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)

/**
 * 实例化并调用所有已注册的 BeanFactoryPostProcessor bean。
 * 如果指定了顺序,会尊重该顺序进行调用。
 *
 * 

注意:该方法必须在单例 bean 实例化之前调用。 * * @param beanFactory 要操作的 BeanFactory */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 使用 PostProcessorRegistrationDelegate 工具类来调用所有的 BeanFactoryPostProcessor // 这些处理器可以修改 BeanFactory 的配置,例如添加额外的 BeanDefinition PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 检查是否已经定义了 LoadTimeWeaver(例如通过 @Bean 方法由 ConfigurationClassPostProcessor 注册) // 如果发现 LoadTimeWeaver,则准备进行加载时织入(Load-Time Weaving) if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // 添加 LoadTimeWeaverAwareProcessor,用于处理实现了 LoadTimeWeaverAware 接口的 bean beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // 设置一个临时的 ClassLoader,用于类型匹配 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

说明:

  • 入参 beanFactoryDefaultListableBeanFactoryDefaultListableBeanFactory实现BeanDefinitionRegistry 接口。
  • BeanFactoryPostProcessor 是 Spring 提供的一个扩展点,允许在 BeanFactory 加载了 bean 定义但尚未实例化任何 bean 之前对其进行修改。
  • 此方法会调用所有注册的 BeanFactoryPostProcessor,包括:
    • 用户自定义的后置处理器;
    • Spring 内部的一些关键处理器,如 ConfigurationClassPostProcessor(负责处理 @Configuration 类)。
  • LoadTimeWeaver 是 AOP 等功能中用于在类加载时进行字节码增强的组件。如果检测到它的存在,Spring 会为此上下文准备好相关的支持。

5.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...) 方法

/**
 * 调用所有已注册的 BeanFactoryPostProcessor。
 * 包括通过上下文显式传入的处理器(beanFactoryPostProcessors),
 * 以及容器中定义为 bean 的 BeanFactoryPostProcessor 实例。
 *
 * 

此方法会优先处理 BeanDefinitionRegistryPostProcessor, * 因为其可以修改 BeanDefinition 注册信息。 * *

调用顺序遵循以下优先级规则: * 1. 实现 PriorityOrdered 接口的处理器; * 2. 实现 Ordered 接口的处理器; * 3. 其他无排序接口的处理器。 * * @param beanFactory 当前应用上下文使用的 BeanFactory * @param beanFactoryPostProcessors 上下文显式注册的 BeanFactoryPostProcessor 列表 */ public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 注意:虽然看起来可以简化多层循环和多个列表的操作,但这样做是故意设计的。 // 必须确保按照 PriorityOrdered 和 Ordered 的契约正确执行后处理器。 // 修改此方法前,请查看 Spring 官方仓库中被拒绝的相关 PR,避免引入破坏性变更。 Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry registry) { // 如果是 BeanDefinitionRegistry 类型,则先处理 BeanDefinitionRegistryPostProcessor List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 遍历显式传入的 postProcessors,区分出 BeanDefinitionRegistryPostProcessor for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) { // 直接调用其 postProcessBeanDefinitionRegistry 方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 第一步:调用实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor // 从 beanFactory 获取 BeanDefinitionRegistryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 调用 BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); // 第二步:调用实现 Ordered 接口的 BeanDefinitionRegistryPostProcessor postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 调用 BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); // 第三步:调用其余未处理的 BeanDefinitionRegistryPostProcessor,直到没有新的出现 boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { // 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; // 如果新增了处理器,继续循环 } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 调用 BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); } // 最后再统一调用这些处理器的 postProcessBeanFactory 方法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // 如果不是 BeanDefinitionRegistry 类型,直接调用传入的 BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 再次查找并调用其他 BeanFactoryPostProcessor(非 BeanDefinitionRegistryPostProcessor) String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // 已经在上面处理过,跳过 continue; } if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 第一步:调用实现 PriorityOrdered 的 BeanFactoryPostProcessor sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 第二步:调用实现 Ordered 的 BeanFactoryPostProcessor List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 第三步:调用其余无序的 BeanFactoryPostProcessor List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清除缓存的合并 BeanDefinition,因为可能已被修改(如占位符替换等) beanFactory.clearMetadataCache(); }

为什么要判断 beanFactory instanceof BeanDefinitionRegistry

  • 并非所有的 BeanFactory 都实现BeanDefinitionRegistry
    • 职责分离原则
      • BeanFactory 的核心职责是 管理 Bean 的创建和获取。
      • BeanDefinitionRegistry 的职责是 允许注册新的 Bean 定义(BeanDefinition),属于扩展功能。
    • 避免暴露危险操作
      • 注册 Bean 定义是一种影响容器状态的操作,在某些生产环境或安全敏感环境中应被限制。
      • 通过只让需要此能力的容器实现 BeanDefinitionRegistry,可以控制哪些组件能修改容器结构。
  • 调用之前注册到BeanFactory (DefaultListableBeanFactory) BeanDefinition(BeanDefinitionRegistryPostProcessor),如 ConfigurationClassPostProcessor(负责处理 @Configuration 类)。
  • 如果 BeanFactory 不是 BeanDefinitionRegistry,说明 BeanFactory 没有注册任何 BeanDefinition

调用顺序

步骤 处理器类型 调用顺序 特点
1 BeanDefinitionRegistryPostProcessor + PriorityOrdered 最高优先级 可以修改 BeanDefinition 注册
2 BeanDefinitionRegistryPostProcessor + Ordered 次优先级 同上
3 BeanDefinitionRegistryPostProcessor + 无排序 默认顺序 同上
4 BeanFactoryPostProcessor + PriorityOrdered 第四优先级 修改整个 BeanFactory
5 BeanFactoryPostProcessor + Ordered 第五优先级 同上
6 BeanFactoryPostProcessor + 无排序 最低优先级 同上

⚠️ 注意事项

  • 不能在此阶段初始化 FactoryBean,因为需要保留原始状态供后处理器处理;
  • 必须严格按照 PriorityOrdered > Ordered > 无序 的顺序调用,必须先调用BeanDefinitionRegistryPostProcessor 再调用BeanFactoryPostProcessor ,否则可能导致配置错误或代理失效;
  • 处理完成后清除元数据缓存,因为后处理器可能已经修改了配置(如属性占位符解析、AOP 增强等)。

BeanFactoryPostProcessor 与 BeanDefinitionRegistryPostProcessor区别

6.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(...) 方法

/**
 * 调用给定的 BeanDefinitionRegistryPostProcessor 实例。
 *
 * @param postProcessors 一组实现了 BeanDefinitionRegistryPostProcessor 接口的处理器
 * @param registry       Bean定义注册表,用于注册Bean定义
 * @param applicationStartup 用于跟踪应用程序启动步骤的工具
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, 
        BeanDefinitionRegistry registry, 
        ApplicationStartup applicationStartup) {

    // 遍历所有的 BeanDefinitionRegistryPostProcessor 实例
    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        // 开始一个应用启动步骤,并记录该步骤的相关信息
        StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
                .tag("postProcessor", postProcessor::toString);

        // 调用 postProcessBeanDefinitionRegistry 方法,允许处理器对 BeanDefinitionRegistry 进行处理
        postProcessor.postProcessBeanDefinitionRegistry(registry);

        // 结束当前的应用启动步骤
        postProcessBeanDefRegistry.end();
    }
}

说明:

  • 入参 registryDefaultListableBeanFactoryDefaultListableBeanFactory实现BeanDefinitionRegistry 接口。
  • postProcessor.postProcessBeanDefinitionRegistry(registry)只能使用 DefaultListableBeanFactoryBeanDefinitionRegistry 功能

7.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...) 方法

/**
 * 调用给定的 BeanFactoryPostProcessor 实例。
 *
 * @param postProcessors 一组实现了 BeanFactoryPostProcessor 接口的处理器
 * @param beanFactory    当前使用的 BeanFactory 实例,用于配置和管理 Bean
 */
private static void invokeBeanFactoryPostProcessors(
        Collection<? extends BeanFactoryPostProcessor> postProcessors, 
        ConfigurableListableBeanFactory beanFactory) {

    // 遍历所有的 BeanFactoryPostProcessor 实例
    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        // 启动一个应用启动步骤跟踪(用于性能监控),并附加当前处理器信息
        StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
                .tag("postProcessor", postProcessor::toString);

        // 调用 postProcessBeanFactory 方法,允许处理器修改 BeanFactory 的配置
        postProcessor.postProcessBeanFactory(beanFactory);

        // 结束该启动步骤的跟踪
        postProcessBeanFactory.end();
    }
}

说明:

  • 入参 beanFactoryDefaultListableBeanFactoryDefaultListableBeanFactory实现BeanDefinitionRegistry 接口。
  • postProcessor.postProcessBeanFactory(beanFactory)只能使用 DefaultListableBeanFactoryBeanFactory 功能

你可能感兴趣的:(spring,boot,spring,boot)