Spring生命周期:Aware接口、InitializingBean与初始化流程的底层原理

29 阅读17分钟

在Spring框架中,Bean的生命周期管理是其核心能力之一。开发者通过实现Aware接口、InitializingBean接口或使用@PostConstruct等注解,可以精确控制Bean的初始化过程。但这些机制的底层是如何协作的?不同场景下(如配置类作为BeanFactoryPostProcessor)它们的行为又会有何变化?

本文将通过源码逐行分析执行流程图解多场景对比测试,深入拆解Spring中Aware接口注入、依赖注入、初始化方法的执行顺序,以及配置类的特殊处理逻辑。


一、Spring Bean生命周期的底层执行链

要理解本文的各类机制,首先需要明确Spring Bean的完整生命周期。简化后的核心流程如下(基于AbstractAutowireCapableBeanFactoryinitializeBean方法):

graph TD

A[实例化Bean] --> B[执行Aware接口方法]
B --> C[依赖注入 Autowired/Resource]
C --> D[执行InitializingBean#afterPropertiesSet]
D --> E[执行PostConstruct初始化方法]
E --> F[Bean准备完成,可供使用]

这一流程的背后,是Spring通过后处理器(BeanPostProcessor)​内置回调接口协同完成的。接下来,我们通过源码逐行分析每个阶段的具体实现。


1.1 实例化阶段:Bean的创建

Spring通过反射调用Bean的构造函数完成实例化。对于普通Bean,实例化发生在AbstractAutowireCapableBeanFactorycreateBeanInstance方法中:

// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 构造函数解析逻辑(如选择无参构造、带参构造)
    return instantiateBean(beanName, mbd);
}

对于配置类(@Configuration),Spring会通过CGLIB生成代理类,确保配置类的@Bean方法被正确代理(避免重复实例化)。这一过程由ConfigurationClassPostProcessor触发。


1.2 Aware接口注入:Spring的内置回调

Aware接口(如BeanNameAwareApplicationContextAware)是Spring提供的“早期注入”机制,用于在Bean实例化后、依赖注入前注入容器相关的元信息。

1.2.1 调用时机:invokeAwareMethods

在Bean实例化完成后,Spring会调用AbstractAutowireCapableBeanFactoryinvokeAwareMethods方法,检查Bean是否实现了Aware接口,并触发对应方法:

// AbstractAutowireCapableBeanFactory.java
private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName); // 触发BeanNameAware
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); // 触发BeanFactoryAware
        }
    }
}

关键结论​:Aware接口的回调发生在Bean实例化后(构造函数执行完成),但在依赖注入(populateBean)之前。因此,通过Aware接口获取的Bean名称或上下文可以用于后续的依赖注入逻辑。


1.3 依赖注入:@Autowired与后处理器

依赖注入(DI)是Spring的核心功能之一,主要由AutowiredAnnotationBeanPostProcessor(处理@Autowired)和CommonAnnotationBeanPostProcessor(处理@Resource)完成。

1.3.1 后处理器的注册顺序

在容器启动时,Spring会通过PostProcessorRegistrationDelegate注册所有后处理器。其中:

  • AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor属于“Bean工厂后处理器”(BeanFactoryPostProcessor),会在refresh()方法的postProcessBeanFactory阶段注册。
  • 其他后处理器(如ApplicationListenerDetector)属于“Bean后处理器”(BeanPostProcessor),会在postProcessBeanDefinitionRegistry阶段注册。

1.3.2 @Autowired的注入流程

AutowiredAnnotationBeanPostProcessorpostProcessProperties方法负责处理@Autowired注解:

// AutowiredAnnotationBeanPostProcessor.java
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // ... 解析@Autowired注解的字段/方法
    inject(bean, beanName, pvs); // 实际注入逻辑
    return pvs;
}

private void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) {
    // 通过反射调用setter方法或直接注入字段
    // 例如:找到@Autowired标记的字段,获取对应的Bean实例并赋值
}

关键结论​:@Autowired的注入发生在依赖注入阶段(populateBean),因此在Aware接口回调之后、InitializingBean之前。


1.4 初始化方法:InitializingBean@PostConstruct

Spring提供了两种初始化回调机制:

  • InitializingBean#afterPropertiesSet:Spring内置接口,由AbstractAutowireCapableBeanFactory直接调用。
  • @PostConstruct:JSR-250标准注解,由CommonAnnotationBeanPostProcessor处理。

1.4.1 InitializingBean#afterPropertiesSet的调用

在依赖注入完成后,Spring会调用AbstractAutowireCapableBeanFactoryinvokeInitMethods方法触发InitializingBean接口:

// AbstractAutowireCapableBeanFactory.java
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (bean instanceof InitializingBean) {
        ((InitializingBean) bean).afterPropertiesSet(); // 触发InitializingBean
    }
    if (mbd != null && mbd.getInitMethodName() != null) {
        invokeCustomInitMethod(beanName, bean, mbd.getInitMethodName()); // 自定义init-method
    }
}

1.4.2 @PostConstruct的调用

CommonAnnotationBeanPostProcessor实现了BeanPostProcessor接口,在postProcessBeforeInitialization方法中处理@PostConstruct

// CommonAnnotationBeanPostProcessor.java
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    // ... 处理@PostConstruct注解的方法
    invokeAnnotatedMethod(bean, beanName, PostConstruct.class); // 调用@PostConstruct方法
    return bean;
}

关键结论​:@PostConstruct的执行顺序早于InitializingBean#afterPropertiesSet。这是因为CommonAnnotationBeanPostProcessor作为BeanPostProcessor,在initializeBean阶段被优先调用。


二、场景1:基础测试——验证内置机制的执行顺序

2.1 测试代码说明

我们定义了一个业务Bean AwareAndInitializingBean,实现了BeanNameAwareApplicationContextAwareInitializingBean接口,并包含@Autowired注入和@PostConstruct方法:

  /**
     * 业务Bean:演示Aware接口、InitializingBean、@Autowired@PostConstruct的完整执行顺序
     * 底层关联源码:AbstractAutowireCapableBeanFactory#initializeBean()
     */
    @Slf4j
    static class AwareAndInitializingBean implements BeanNameAware, ApplicationContextAware, InitializingBean {

        // 记录Bean名称(由BeanNameAware注入)
        private String beanName;

        /**
         * 1. BeanNameAware接口方法:在Bean实例化后,设置Bean名称
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → invokeAwareMethods()
         * 源码片段:
         * <pre>{@code
         *  if (bean instanceof Aware) {
         *      if (bean instanceof BeanNameAware) ((BeanNameAware) bean).setBeanName(beanName);
         *      if (bean instanceof BeanClassLoaderAware) ...;
         *      if (bean instanceof BeanFactoryAware) ...;
         *  }
         * }</pre>
         */
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
            log.info("[AwareAndInitializingBean] [1] BeanNameAware.setBeanName() 被调用,Bean名称:{}", name);
        }

        /**
         * 2. ApplicationContextAware接口方法:注入ApplicationContext
         * 底层调用链同上(invokeAwareMethods())
         * 源码说明:ApplicationContextAware的实现会被BeanFactory通过BeanFactoryAwareProcessor处理
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            log.info("[AwareAndInitializingBean] [2] ApplicationContextAware.setApplicationContext() 被调用,上下文:{}", applicationContext);
        }

        /**
         * 3. InitializingBean接口方法:属性注入完成后初始化
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → invokeInitMethods()
         * 源码片段:
         * <pre>{@code
         *  if (bean instanceof InitializingBean) {
         *      ((InitializingBean) bean).afterPropertiesSet();
         *  }
         * }</pre>
         */
        @Override
        public void afterPropertiesSet() {
            log.info("[AwareAndInitializingBean] [3] InitializingBean.afterPropertiesSet() 被调用,Bean名称:{}", beanName);
        }

        /**
         * 4. @Autowired依赖注入:由AutowiredAnnotationBeanPostProcessor处理
         * 底层调用链:AbstractAutowireCapableBeanFactory#populateBean() → AutowiredAnnotationBeanPostProcessor#postProcessProperties()
         * 源码片段:
         * <pre>{@code
         *  public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
         *      inject(bean, beanName, pvs);
         *  }
         *  private void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) {
         *      // 通过反射注入@Autowired字段/方法
         *  }
         * }</pre>
         */
        @Autowired
        public void autowiredTest(ApplicationContext context) {
            log.info("[AwareAndInitializingBean] [4] @Autowired注入成功,注入的ApplicationContext:{}", context);
        }

        /**
         * 5. @PostConstruct初始化方法:由CommonAnnotationBeanPostProcessor处理
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → applyBeanPostProcessorsBeforeInitialization()
         * 源码片段:
         * <pre>{@code
         * public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
         *  for (BeanPostProcessor processor : getBeanPostProcessors()) {
         *      if (processor instanceof CommonAnnotationBeanPostProcessor) {
         *          ((CommonAnnotationBeanPostProcessor) processor).postProcessBeforeInitialization(existingBean, beanName);
         *          }
         *      }
         *  }
         * }</pre>
         */
        @PostConstruct
        public void postConstructTest() {
            log.info("[AwareAndInitializingBean] [5] @PostConstruct.postConstructTest() 被调用");
        }
            }

2.2 执行流程与日志分析

启动容器后,控制台输出如下(关键日志已标注序号):

02:07:03.620 [main] INFO com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean -- [AwareAndInitializingBean] [4] @Autowired注入成功,注入的ApplicationContext:org.springframework.context.support.GenericApplicationContext@66d2e7d9, started on Tue Jun 17 02:07:03 CST 2025
02:07:03.637 [main] INFO com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean -- [AwareAndInitializingBean] [1] BeanNameAware.setBeanName() 被调用,Bean名称:com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean
02:07:03.637 [main] INFO com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean -- [AwareAndInitializingBean] [2] ApplicationContextAware.setApplicationContext() 被调用,上下文:org.springframework.context.support.GenericApplicationContext@66d2e7d9, started on Tue Jun 17 02:07:03 CST 2025
02:07:03.638 [main] INFO com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean -- [AwareAndInitializingBean] [5] @PostConstruct.postConstructTest() 被调用
02:07:03.638 [main] INFO com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean -- [AwareAndInitializingBean] [3] InitializingBean.afterPropertiesSet() 被调用,Bean名称:com.dwl.aware_and_initializing_bean.AwareAndInitializingBeanCase$AwareAndInitializingBean

2.2.1 流程拆解

  1. 实例化Bean​:Spring通过无参构造函数创建AwareAndInitializingBean实例。
  2. 触发Aware接口​:调用invokeAwareMethods,依次执行BeanNameAwareApplicationContextAware
  3. 依赖注入(@Autowired)​​:AutowiredAnnotationBeanPostProcessor处理@Autowired注解,注入ApplicationContext
  4. 执行@PostConstruct​:CommonAnnotationBeanPostProcessor触发@PostConstruct方法。
  5. 执行InitializingBean​:AbstractAutowireCapableBeanFactory调用afterPropertiesSet方法。

2.2.2 源码验证

  • BeanNameAwareApplicationContextAware的触发:AbstractAutowireCapableBeanFactory#invokeAwareMethods
  • @Autowired的注入:AutowiredAnnotationBeanPostProcessor#postProcessProperties
  • @PostConstruct的触发:CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization
  • InitializingBean的触发:AbstractAutowireCapableBeanFactory#invokeInitMethods

三、场景2:配置类作为BeanFactoryPostProcessor——依赖注入失效之谜

3.1 问题现象

配置类AwareAndInitializingConfigA通过@Bean返回BeanFactoryPostProcessor,其内部@Autowired@PostConstruct方法未生效:

    @Slf4j
    @Configuration
    static class AwareAndInitializingConfigA {

        /**
         * @Bean方法返回BeanFactoryPostProcessor,导致配置类被标记为BeanFactoryPostProcessor类型 底层处理:ConfigurationClassPostProcessor会检测到@Bean方法返回BeanFactoryPostProcessor,并将其加入bfpp列表
         * 源码片段(ConfigurationClassParser):
         * if (mbd.getFactoryMethodName() != null) {
         * // 处理@Bean方法
         * } else {
         * // 普通方法,直接注册Bean定义
         * }
         * 最终,BeanFactoryPostProcessor类型的Bean会被收集到AbstractApplicationContext的beanFactoryPostProcessors列表
         */
        @Bean
        public BeanFactoryPostProcessor processor() {
            log.info("[AwareAndInitializingConfigA] [X] BeanFactoryPostProcessor.processor() 被调用(配置类实例化阶段)");
            return beanFactory -> {
                log.info("[AwareAndInitializingConfigA] [X] BeanFactoryPostProcessor处理Bean定义(postProcessBeanFactory)");
            };
        }

        /**
         * 配置类的@Autowired方法:预期失效(因配置类实例化早于AutowiredAnnotationBeanPostProcessor)
         * 底层原因:配置类作为BeanFactoryPostProcessor会被优先实例化(在refresh()的invokeBeanFactoryPostProcessors阶段)
         * 此时,AutowiredAnnotationBeanPostProcessor尚未注册,无法处理@Autowired
         */
        @Autowired
        public void configAutowiredTest(ApplicationContext context) {
            // 场景2中此日志不会输出(@Autowired失效)
            log.info("[AwareAndInitializingConfigA] [X] 配置类@Autowired注入成功(预期场景2不输出)");
        }

        /**
         * 配置类的@PostConstruct方法:预期失效(因CommonAnnotationBeanPostProcessor未注册)
         * 底层原因同上:配置类实例化时,CommonAnnotationBeanPostProcessor尚未注册
         */
        @PostConstruct
        public void configPostConstructTest() {
            // 场景2中此日志不会输出(@PostConstruct失效)
            log.info("[AwareAndInitializingConfigA] [X] 配置类@PostConstruct执行(预期场景2不输出)");
        }

//        /**
//         * 配置类的InitializingBean方法:正常生效(配置类是Bean,触发InitializingBean)
//         * 底层原因:配置类作为Bean,其初始化流程与普通Bean一致(即使包含@Bean方法)
//         */
//        @Override
//        public void afterPropertiesSet() {
//            log.info("[AwareAndInitializingConfigA] [3] 配置类InitializingBean.afterPropertiesSet() 被调用");
//        }
    }

3.2 底层原因分析

3.2.1 配置类的特殊生命周期

Spring对@Configuration类有特殊处理:通过ConfigurationClassPostProcessor解析配置类,生成代理对象,并将其@Bean方法转换为Bean定义。但配置类本身也是一个Bean,其生命周期与其他Bean不同。

3.2.2 BeanFactoryPostProcessor的优先级

当配置类实现BeanFactoryPostProcessor(或通过@Bean返回BeanFactoryPostProcessor)时,Spring会在refresh()方法的invokeBeanFactoryPostProcessors阶段优先实例化并执行这些后处理器:

// AbstractApplicationContext.java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // ... 触发所有BeanFactoryPostProcessor的postProcessBeanFactory方法
}

3.2.3 关键时间点对比

阶段Aware接口注入@Autowired注入@PostConstruct执行BeanFactoryPostProcessor执行
普通Bean实例化后依赖注入阶段初始化阶段
实现BeanFactoryPostProcessor的Bean实例化后早于普通Bean早于普通Bean实例化后立即执行

核心矛盾​:配置类作为BeanFactoryPostProcessor时,其@Autowired@PostConstruct需要在配置类实例化后执行,但此时:

  • AutowiredAnnotationBeanPostProcessor尚未注册(它属于BeanPostProcessor,在postProcessBeanDefinitionRegistry阶段注册)。
  • CommonAnnotationBeanPostProcessor也未注册,无法处理@PostConstruct

因此,配置类的@Autowired@PostConstruct无法被正确触发。


3.3 源码验证:配置类的实例化时机

ConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry方法会提前解析配置类:

// ConfigurationClassPostProcessor.java
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // ... 解析@Configuration类,生成BeanDefinition
    for (BeanDefinitionHolder holder : configClasses) {
        processBeanDefinition(holder, registry); // 注册@Bean方法对应的BeanDefinition
    }
}

配置类的实例化由BeanDefinition驱动,发生在BeanFactoryPostProcessor执行阶段(invokeBeanFactoryPostProcessors),早于BeanPostProcessor的注册阶段。因此,配置类的@Autowired@PostConstruct无法被后续的后处理器处理。


四、场景3:配置类实现Aware接口——Spring的保护机制

4.1 正常执行的日志

配置类AwareAndInitializingConfigB实现了ApplicationContextAwareInitializingBean接口,其内部@Autowired@PostConstruct正常生效:

/**
     * 配置类B:演示配置类正常实现Aware接口和InitializingBean的行为
     * 底层保障:配置类作为特殊Bean,其初始化流程受Spring保护,确保Aware接口和依赖注入正常执行
     */
    @Slf4j
    @Configuration
    static class AwareAndInitializingConfigB implements ApplicationContextAware, InitializingBean {

        /**
         * 配置类的ApplicationContextAware方法:正常生效(配置类实例化时已注册内置后处理器)
         * 底层原因:配置类由ConfigurationClassPostProcessor处理,其实例化晚于AutowiredAnnotationBeanPostProcessor注册
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            log.info("[AwareAndInitializingConfigB] [2] 配置类ApplicationContextAware.setApplicationContext() 被调用");
        }

        /**
         * 配置类的InitializingBean方法:正常生效(早于@PostConstruct)
         */
        @Override
        public void afterPropertiesSet() {
            log.info("[AwareAndInitializingConfigB] [3] 配置类InitializingBean.afterPropertiesSet() 被调用");
        }

        /**
         * 配置类的@Bean方法:返回BeanFactoryPostProcessor(不影响自身初始化)
         * 底层处理:ConfigurationClassPostProcessor会识别此@Bean方法,并生成代理类确保单例
         */
        @Bean
        public BeanFactoryPostProcessor processor() {
            log.info("[AwareAndInitializingConfigB] [X] 配置类BeanFactoryPostProcessor.processor() 被调用(正常阶段)");
            return beanFactory -> {
                log.info("[AwareAndInitializingConfigB] [X] 配置类BeanFactoryPostProcessor处理Bean定义");
            };
        }

        /**
         * 配置类的@Autowired方法:正常生效(BP已注册)
         */
        @Autowired
        public void configAutowiredTest(ApplicationContext context) {
            log.info("[AwareAndInitializingConfigB] [4] 配置类@Autowired注入成功");
        }

        /**
         * 配置类的@PostConstruct方法:正常生效(BP已注册)
         */
        @PostConstruct
        public void configPostConstructTest() {
            log.info("[AwareAndInitializingConfigB] [5] 配置类@PostConstruct执行");
        }
    }

4.2 底层保障机制

配置类虽然特殊,但其作为Bean的生命周期仍受Spring保护。关键在于:

4.2.1 配置类的代理机制

ConfigurationClassPostProcessor会为配置类生成CGLIB代理,确保配置类的初始化流程与普通Bean一致。代理类会延迟执行@Bean方法,直到容器刷新完成,从而避免与BeanFactoryPostProcessor的执行阶段冲突。

4.2.2 后处理器的注册顺序

AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorpostProcessBeanDefinitionRegistry阶段之前已由PostProcessorRegistrationDelegate注册。因此,配置类的实例化晚于这些后处理器的注册,能够正常触发依赖注入和初始化回调。

4.2.3 执行流程验证

配置类AwareAndInitializingConfigB的执行顺序与普通Bean一致:

  1. 实例化 → 2. Aware接口注入 → 3. @Autowired注入 → 4. @PostConstruct执行 → 5. InitializingBean执行 → 6. @Bean方法执行(由代理延迟触发)。

五、关键结论总结

机制/场景执行顺序/行为核心原因
Aware接口(BeanNameAware等)实例化后、依赖注入前触发AbstractAutowireCapableBeanFactory#invokeAwareMethods在实例化后立即调用
@Autowired依赖注入Aware接口之后、InitializingBean之前触发AutowiredAnnotationBeanPostProcessor作为BeanPostProcessor在依赖注入阶段执行
@PostConstruct初始化方法@Autowired之后、InitializingBean之前触发CommonAnnotationBeanPostProcessor作为BeanPostProcessorpostProcessBeforeInitialization阶段执行
配置类作为BeanFactoryPostProcessor实例化早于AutowiredAnnotationBeanPostProcessor,导致@Autowired/@PostConstruct失效ConfigurationClassPostProcessor提前实例化配置类,此时后处理器未注册
配置类实现Aware接口与普通Bean一致,Aware接口、@Autowired、@PostConstruct正常触发配置类由CGLIB代理延迟@Bean方法执行,且后处理器已提前注册

六、实践建议

6.1 避免配置类作为BeanFactoryPostProcessor

除非明确需要操作Bean定义(如修改@Bean方法的属性),否则应让配置类专注于Bean的声明。避免因实例化时机过早导致依赖注入失效。

6.2 明确初始化顺序

若需要控制多个初始化方法的顺序(如@PostConstruct与自定义初始化方法),可通过以下方式调整:

  • 使用@Order注解(仅对@PostConstructInitializingBean有效)。
  • 实现SmartLifecycle接口,通过getPhase()方法控制生命周期阶段。

6.3 理解后处理器的注册顺序

BeanPostProcessor的注册顺序直接影响依赖注入和初始化逻辑。Spring默认按以下顺序注册常用后处理器:

  1. AutowiredAnnotationBeanPostProcessor(处理@Autowired
  2. CommonAnnotationBeanPostProcessor(处理@PostConstruct
  3. ApplicationListenerDetector(处理事件监听器)

七、Spring Boot中的自动配置

Spring Boot的自动配置(@EnableAutoConfiguration)本质上是通过@Configuration类实现的。这些配置类可能包含@Bean方法返回BeanFactoryPostProcessor(如DataSourceInitializer)。理解本文的场景2有助于解释以下问题:

  • 为什么自动配置类中的@Autowired有时需要@Lazy注解?
  • 为什么自动配置类的@PostConstruct方法在容器启动早期执行?

答案与配置类的实例化时机和后处理器注册顺序密切相关:自动配置类作为BeanFactoryPostProcessor,其实例化和执行早于大部分业务Bean,因此依赖注入需依赖Spring的保护机制(如延迟加载)。


完整代码

package com.dwl.aware_and_initializing_bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

import javax.annotation.PostConstruct;

/**
 * @ClassName AwareAndInitializingBeanCase
 * @Description 演示Spring中Aware接口、InitializingBean接口与依赖注入、初始化方法的执行顺序及作用域
 * 关键结论:
 * 1. Aware接口(如BeanNameAware、ApplicationContextAware)是Spring内置的注入机制,优先级高于后处理器
 * 2. InitializingBean接口的afterPropertiesSet方法是Spring内置的初始化回调,早于@PostConstruct执行
 * 3. @Autowired@PostConstruct依赖BeanPostProcessor( AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor)
 * 4. 当@Configuration配置类被注册为BeanFactoryPostProcessor时,可能导致其内部@Autowired失效(因BP未提前注册)
 * @Version 1.0.0
 * @Date 2025
 * @Author By Dwl
 */
@Slf4j
public class AwareAndInitializingBeanCase {


    public static void main(String[] args) {
        log.info("===== 启动容器,开始执行Aware/InitializingBean完整生命周期 =====");

        // 场景1:基础测试(仅注册业务Bean,验证内置机制)
        testBasicAwareAndInit();

        // 场景2:配置类作为BeanFactoryPostProcessor(验证@Autowired失效问题)
        testConfigAsBeanFactoryPostProcessor();

        // 场景3:配置类实现Aware接口(验证内置机制不受影响)
        testConfigImplementAware();
    }

    /**
     * 场景1:基础测试(仅注册业务Bean)
     * 底层流程:容器刷新 → 注册内置后处理器 → 实例化Bean → 执行Aware接口 → 依赖注入 → @PostConstruct → InitializingBean
     */
    private static void testBasicAwareAndInit() {
        log.info("\n===== 场景1:基础测试(仅注册业务Bean) =====");
        GenericApplicationContext context = new GenericApplicationContext();

        // 注册业务Bean(无额外配置,Spring自动注册内置后处理器)
        context.registerBean(AwareAndInitializingBean.class);

//        context.registerBean(CommonAnnotationBeanPostProcessor.class);  // 处理@PostConstruct
//        context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 处理@Autowired


        // 触发容器刷新(核心流程)
        context.refresh();

        context.close();
    }

    /**
     * 场景2:配置类作为BeanFactoryPostProcessor
     * 底层问题:BeanFactoryPostProcessor实例化早于AutowiredAnnotationBeanPostProcessor,导致其内部@Autowired失效
     */
    private static void testConfigAsBeanFactoryPostProcessor() {
        log.info("\n===== 场景2:配置类作为BeanFactoryPostProcessor =====");
        GenericApplicationContext context = new GenericApplicationContext();

        // 注册配置类(含@Bean返回BeanFactoryPostProcessor)
        context.registerBean(AwareAndInitializingConfigA.class);

        // 显式注册后处理器(但配置类实例化早于这些后处理器)
        context.registerBean(CommonAnnotationBeanPostProcessor.class);  // 处理@PostConstruct
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 处理@Autowired
        context.registerBean(ConfigurationClassPostProcessor.class); // 处理@Configuration

        context.refresh();
        context.close();
    }

    /**
     * 场景3:配置类实现Aware接口
     * 底层保障:配置类作为特殊Bean,其初始化流程受Spring保护,确保Aware接口和依赖注入正常执行
     */
    private static void testConfigImplementAware() {
        log.info("\n===== 场景3:配置类实现Aware接口 =====");
        GenericApplicationContext context = new GenericApplicationContext();

        // 注册配置类(实现ApplicationContextAware)
        context.registerBean(AwareAndInitializingConfigB.class);

        // 注册后处理器(确保业务Bean的依赖注入生效)
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);

        // 注册配置类处理BeanFactoryPostProcessor(配置类自身的@Bean会被处理)
        context.registerBean(ConfigurationClassPostProcessor.class);

        context.refresh();
        context.close();
    }


    /**
     * 业务Bean:演示Aware接口、InitializingBean、@Autowired@PostConstruct的完整执行顺序
     * 底层关联源码:AbstractAutowireCapableBeanFactory#initializeBean()
     */
    @Slf4j
    static class AwareAndInitializingBean implements BeanNameAware, ApplicationContextAware, InitializingBean {

        // 记录Bean名称(由BeanNameAware注入)
        private String beanName;

        /**
         * 1. BeanNameAware接口方法:在Bean实例化后,设置Bean名称
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → invokeAwareMethods()
         * 源码片段:
         * <pre>{@code
         *  if (bean instanceof Aware) {
         *      if (bean instanceof BeanNameAware) ((BeanNameAware) bean).setBeanName(beanName);
         *      if (bean instanceof BeanClassLoaderAware) ...;
         *      if (bean instanceof BeanFactoryAware) ...;
         *  }
         * }</pre>
         */
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
            log.info("[AwareAndInitializingBean] [1] BeanNameAware.setBeanName() 被调用,Bean名称:{}", name);
        }

        /**
         * 2. ApplicationContextAware接口方法:注入ApplicationContext
         * 底层调用链同上(invokeAwareMethods())
         * 源码说明:ApplicationContextAware的实现会被BeanFactory通过BeanFactoryAwareProcessor处理
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            log.info("[AwareAndInitializingBean] [2] ApplicationContextAware.setApplicationContext() 被调用,上下文:{}", applicationContext);
        }

        /**
         * 3. InitializingBean接口方法:属性注入完成后初始化
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → invokeInitMethods()
         * 源码片段:
         * <pre>{@code
         *  if (bean instanceof InitializingBean) {
         *      ((InitializingBean) bean).afterPropertiesSet();
         *  }
         * }</pre>
         */
        @Override
        public void afterPropertiesSet() {
            log.info("[AwareAndInitializingBean] [3] InitializingBean.afterPropertiesSet() 被调用,Bean名称:{}", beanName);
        }

        /**
         * 4. @Autowired依赖注入:由AutowiredAnnotationBeanPostProcessor处理
         * 底层调用链:AbstractAutowireCapableBeanFactory#populateBean() → AutowiredAnnotationBeanPostProcessor#postProcessProperties()
         * 源码片段:
         * <pre>{@code
         *  public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
         *      inject(bean, beanName, pvs);
         *  }
         *  private void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) {
         *      // 通过反射注入@Autowired字段/方法
         *  }
         * }</pre>
         */
        @Autowired
        public void autowiredTest(ApplicationContext context) {
            log.info("[AwareAndInitializingBean] [4] @Autowired注入成功,注入的ApplicationContext:{}", context);
        }

        /**
         * 5. @PostConstruct初始化方法:由CommonAnnotationBeanPostProcessor处理
         * 底层调用链:AbstractAutowireCapableBeanFactory#initializeBean() → applyBeanPostProcessorsBeforeInitialization()
         * 源码片段:
         * <pre>{@code
         * public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
         *  for (BeanPostProcessor processor : getBeanPostProcessors()) {
         *      if (processor instanceof CommonAnnotationBeanPostProcessor) {
         *          ((CommonAnnotationBeanPostProcessor) processor).postProcessBeforeInitialization(existingBean, beanName);
         *          }
         *      }
         *  }
         * }</pre>
         */
        @PostConstruct
        public void postConstructTest() {
            log.info("[AwareAndInitializingBean] [5] @PostConstruct.postConstructTest() 被调用");
        }
    }


    /**
     * 配置类A:演示配置类作为BeanFactoryPostProcessor时的特殊行为
     * 底层问题:配置类被当作BeanFactoryPostProcessor优先实例化,此时AutowiredAnnotationBeanPostProcessor未注册,导致其@Autowired失效
     */
    @Slf4j
    @Configuration
    static class AwareAndInitializingConfigA {

        /**
         * @Bean方法返回BeanFactoryPostProcessor,导致配置类被标记为BeanFactoryPostProcessor类型 底层处理:ConfigurationClassPostProcessor会检测到@Bean方法返回BeanFactoryPostProcessor,并将其加入bfpp列表
         * 源码片段(ConfigurationClassParser):
         * if (mbd.getFactoryMethodName() != null) {
         * // 处理@Bean方法
         * } else {
         * // 普通方法,直接注册Bean定义
         * }
         * 最终,BeanFactoryPostProcessor类型的Bean会被收集到AbstractApplicationContext的beanFactoryPostProcessors列表
         */
        @Bean
        public BeanFactoryPostProcessor processor() {
            log.info("[AwareAndInitializingConfigA] [X] BeanFactoryPostProcessor.processor() 被调用(配置类实例化阶段)");
            return beanFactory -> {
                log.info("[AwareAndInitializingConfigA] [X] BeanFactoryPostProcessor处理Bean定义(postProcessBeanFactory)");
            };
        }

        /**
         * 配置类的@Autowired方法:预期失效(因配置类实例化早于AutowiredAnnotationBeanPostProcessor)
         * 底层原因:配置类作为BeanFactoryPostProcessor会被优先实例化(在refresh()的invokeBeanFactoryPostProcessors阶段)
         * 此时,AutowiredAnnotationBeanPostProcessor尚未注册,无法处理@Autowired
         */
        @Autowired
        public void configAutowiredTest(ApplicationContext context) {
            // 场景2中此日志不会输出(@Autowired失效)
            log.info("[AwareAndInitializingConfigA] [X] 配置类@Autowired注入成功(预期场景2不输出)");
        }

        /**
         * 配置类的@PostConstruct方法:预期失效(因CommonAnnotationBeanPostProcessor未注册)
         * 底层原因同上:配置类实例化时,CommonAnnotationBeanPostProcessor尚未注册
         */
        @PostConstruct
        public void configPostConstructTest() {
            // 场景2中此日志不会输出(@PostConstruct失效)
            log.info("[AwareAndInitializingConfigA] [X] 配置类@PostConstruct执行(预期场景2不输出)");
        }

//        /**
//         * 配置类的InitializingBean方法:正常生效(配置类是Bean,触发InitializingBean)
//         * 底层原因:配置类作为Bean,其初始化流程与普通Bean一致(即使包含@Bean方法)
//         */
//        @Override
//        public void afterPropertiesSet() {
//            log.info("[AwareAndInitializingConfigA] [3] 配置类InitializingBean.afterPropertiesSet() 被调用");
//        }
    }

    /**
     * 配置类B:演示配置类正常实现Aware接口和InitializingBean的行为
     * 底层保障:配置类作为特殊Bean,其初始化流程受Spring保护,确保Aware接口和依赖注入正常执行
     */
    @Slf4j
    @Configuration
    static class AwareAndInitializingConfigB implements ApplicationContextAware, InitializingBean {

        /**
         * 配置类的ApplicationContextAware方法:正常生效(配置类实例化时已注册内置后处理器)
         * 底层原因:配置类由ConfigurationClassPostProcessor处理,其实例化晚于AutowiredAnnotationBeanPostProcessor注册
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            log.info("[AwareAndInitializingConfigB] [2] 配置类ApplicationContextAware.setApplicationContext() 被调用");
        }

        /**
         * 配置类的InitializingBean方法:正常生效(早于@PostConstruct)
         */
        @Override
        public void afterPropertiesSet() {
            log.info("[AwareAndInitializingConfigB] [3] 配置类InitializingBean.afterPropertiesSet() 被调用");
        }

        /**
         * 配置类的@Bean方法:返回BeanFactoryPostProcessor(不影响自身初始化)
         * 底层处理:ConfigurationClassPostProcessor会识别此@Bean方法,并生成代理类确保单例
         */
        @Bean
        public BeanFactoryPostProcessor processor() {
            log.info("[AwareAndInitializingConfigB] [X] 配置类BeanFactoryPostProcessor.processor() 被调用(正常阶段)");
            return beanFactory -> {
                log.info("[AwareAndInitializingConfigB] [X] 配置类BeanFactoryPostProcessor处理Bean定义");
            };
        }

        /**
         * 配置类的@Autowired方法:正常生效(BP已注册)
         */
        @Autowired
        public void configAutowiredTest(ApplicationContext context) {
            log.info("[AwareAndInitializingConfigB] [4] 配置类@Autowired注入成功");
        }

        /**
         * 配置类的@PostConstruct方法:正常生效(BP已注册)
         */
        @PostConstruct
        public void configPostConstructTest() {
            log.info("[AwareAndInitializingConfigB] [5] 配置类@PostConstruct执行");
        }
    }

}