在Spring框架中,Bean的生命周期管理是其核心能力之一。开发者通过实现Aware
接口、InitializingBean
接口或使用@PostConstruct
等注解,可以精确控制Bean的初始化过程。但这些机制的底层是如何协作的?不同场景下(如配置类作为BeanFactoryPostProcessor
)它们的行为又会有何变化?
本文将通过源码逐行分析、执行流程图解和多场景对比测试,深入拆解Spring中Aware接口注入、依赖注入、初始化方法的执行顺序,以及配置类的特殊处理逻辑。
一、Spring Bean生命周期的底层执行链
要理解本文的各类机制,首先需要明确Spring Bean的完整生命周期。简化后的核心流程如下(基于AbstractAutowireCapableBeanFactory
的initializeBean
方法):
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,实例化发生在AbstractAutowireCapableBeanFactory
的createBeanInstance
方法中:
// 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接口(如BeanNameAware
、ApplicationContextAware
)是Spring提供的“早期注入”机制,用于在Bean实例化后、依赖注入前注入容器相关的元信息。
1.2.1 调用时机:invokeAwareMethods
在Bean实例化完成后,Spring会调用AbstractAutowireCapableBeanFactory
的invokeAwareMethods
方法,检查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
注册所有后处理器。其中:
AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
属于“Bean工厂后处理器”(BeanFactoryPostProcessor
),会在refresh()
方法的postProcessBeanFactory
阶段注册。- 其他后处理器(如
ApplicationListenerDetector
)属于“Bean后处理器”(BeanPostProcessor
),会在postProcessBeanDefinitionRegistry
阶段注册。
1.3.2 @Autowired
的注入流程
AutowiredAnnotationBeanPostProcessor
的postProcessProperties
方法负责处理@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会调用AbstractAutowireCapableBeanFactory
的invokeInitMethods
方法触发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
,实现了BeanNameAware
、ApplicationContextAware
、InitializingBean
接口,并包含@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 流程拆解
- 实例化Bean:Spring通过无参构造函数创建
AwareAndInitializingBean
实例。 - 触发Aware接口:调用
invokeAwareMethods
,依次执行BeanNameAware
和ApplicationContextAware
。 - 依赖注入(@Autowired):
AutowiredAnnotationBeanPostProcessor
处理@Autowired
注解,注入ApplicationContext
。 - 执行@PostConstruct:
CommonAnnotationBeanPostProcessor
触发@PostConstruct
方法。 - 执行InitializingBean:
AbstractAutowireCapableBeanFactory
调用afterPropertiesSet
方法。
2.2.2 源码验证
BeanNameAware
和ApplicationContextAware
的触发: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 源码验证:配置类的实例化时机
ConfigurationClassPostProcessor
的postProcessBeanDefinitionRegistry
方法会提前解析配置类:
// 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
实现了ApplicationContextAware
和InitializingBean
接口,其内部@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 后处理器的注册顺序
AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
在postProcessBeanDefinitionRegistry
阶段之前已由PostProcessorRegistrationDelegate
注册。因此,配置类的实例化晚于这些后处理器的注册,能够正常触发依赖注入和初始化回调。
4.2.3 执行流程验证
配置类AwareAndInitializingConfigB
的执行顺序与普通Bean一致:
- 实例化 → 2. Aware接口注入 → 3. @Autowired注入 → 4. @PostConstruct执行 → 5. InitializingBean执行 → 6.
@Bean
方法执行(由代理延迟触发)。
五、关键结论总结
机制/场景 | 执行顺序/行为 | 核心原因 |
---|---|---|
Aware接口(BeanNameAware等) | 实例化后、依赖注入前触发 | AbstractAutowireCapableBeanFactory#invokeAwareMethods 在实例化后立即调用 |
@Autowired依赖注入 | Aware接口之后、InitializingBean之前触发 | AutowiredAnnotationBeanPostProcessor 作为BeanPostProcessor 在依赖注入阶段执行 |
@PostConstruct初始化方法 | @Autowired之后、InitializingBean之前触发 | CommonAnnotationBeanPostProcessor 作为BeanPostProcessor 在postProcessBeforeInitialization 阶段执行 |
配置类作为BeanFactoryPostProcessor | 实例化早于AutowiredAnnotationBeanPostProcessor,导致@Autowired/@PostConstruct失效 | ConfigurationClassPostProcessor 提前实例化配置类,此时后处理器未注册 |
配置类实现Aware接口 | 与普通Bean一致,Aware接口、@Autowired、@PostConstruct正常触发 | 配置类由CGLIB代理延迟@Bean 方法执行,且后处理器已提前注册 |
六、实践建议
6.1 避免配置类作为BeanFactoryPostProcessor
除非明确需要操作Bean定义(如修改@Bean
方法的属性),否则应让配置类专注于Bean的声明。避免因实例化时机过早导致依赖注入失效。
6.2 明确初始化顺序
若需要控制多个初始化方法的顺序(如@PostConstruct
与自定义初始化方法),可通过以下方式调整:
- 使用
@Order
注解(仅对@PostConstruct
和InitializingBean
有效)。 - 实现
SmartLifecycle
接口,通过getPhase()
方法控制生命周期阶段。
6.3 理解后处理器的注册顺序
BeanPostProcessor
的注册顺序直接影响依赖注入和初始化逻辑。Spring默认按以下顺序注册常用后处理器:
AutowiredAnnotationBeanPostProcessor
(处理@Autowired
)CommonAnnotationBeanPostProcessor
(处理@PostConstruct
)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执行");
}
}
}