博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。
② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。
③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。
进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。
群公告里还有全网大赛约稿汇总/博客提效工具集/CSDN自动化运营脚本 有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

img

Spring Boot 机制五: Bean 生命周期与后置处理器(BeanPostProcessor)源码深度剖析

本文面向中高级 Spring Boot 工程师,以源码为基础,全面剖析 Bean 的生命周期、后置处理器执行链路、Aware 接口、初始化流程以及 Spring BeanFactory 的完整管理机制。


目录

  1. Bean 生命周期全景图
  2. Bean 创建的完整阶段(含详细源码)
  3. Spring BeanPostProcessor 原理与执行顺序
  4. 常用 BeanPostProcessor 源码解析
  5. Aware 与初始化体系(InitializingBean / @PostConstruct)
  6. 实战:自定义一个 BeanPostProcessor
  7. 如何调试 Bean 生命周期
  8. 关键对比表与总结

1. Bean 生命周期全景图

Spring Bean 的生命周期是 Spring 框架最核心的概念之一。通常我们看到的版本往往只是一张简化图,但完整链路远不止 “创建 → 初始化 → 销毁” 这么简单。

下面是 Spring 官方的 Bean 生命周期完整图(根据源码重绘):

实例化 Instantiation
填充属性 populateBean
执行 Aware 接口
BeanPostProcessor Before Initialization
初始化 Initialization
BeanPostProcessor After Initialization
Bean 准备就绪 Ready for use
容器关闭 destroy

图1:Spring Bean 生命周期全流程(精简)


2. Bean 创建的完整阶段(含详细源码)

2.1 核心入口:doCreateBean()

所有 Bean 的创建最终都落到:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args)

该方法位于:

AbstractAutowireCapableBeanFactory

它做了三件关键的事情:

  1. 实例化 Bean
  2. 属性填充 populateBean
  3. 初始化 initializeBean(包含后置处理器执行)

完整链路 Mermaid 展示:

BeanFactory AbstractAutowireCapableBeanFactory BeanPostProcessor doCreateBean() createBeanInstance() populateBean() postProcessBeforeInitialization() invokeInitMethods() postProcessAfterInitialization() 返回 Bean BeanFactory AbstractAutowireCapableBeanFactory BeanPostProcessor

图2:doCreateBean 执行链路


2.2 Bean 实例化:createBeanInstance()

Spring 提供了 3 种构造方式:

Instantiation 方式 描述
无参构造 默认方式
有参构造 存在依赖注入时使用
工厂方法 使用 @Bean

核心代码:

protected BeanWrapper createBeanInstance(...) {
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(...)
    }
    if (constructorToUse != null) { ... }
    return instantiateBean(beanName, mbd);
}

2.3 属性填充:populateBean()

属性注入发生在这里:

populateBean(beanName, mbd, instanceWrapper);

流程:

  • 处理 @Autowired(AutowiredAnnotationBeanPostProcessor)
  • 处理 @Resource、@Value 等
  • 类型转换 TypeConverter
  • 循环依赖处理

核心代码:

if (hasInstantiationAwareBeanPostProcessors()) {
    for (InstantiationAwareBeanPostProcessor bp : postProcessors) {
        bp.postProcessPropertyValues(...)
    }
}
applyPropertyValues(beanName, mbd, bw, pvs);

注意:

这里会调用 InstantiationAwareBeanPostProcessor,比 BeanPostProcessor 更早执行。


2.4 初始化 initializeBean()

初始化阶段分三步:

  1. 执行 Aware 接口
  2. 执行 BeanPostProcessor Before
  3. 执行初始化方法(@PostConstruct / InitializingBean)
  4. 执行 BeanPostProcessor After

核心代码:

Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

3. BeanPostProcessor 原理与执行顺序

BeanPostProcessor 是 Spring 的“切面总线”,几乎所有高级能力(AOP、事务、校验、@Autowired)都依赖它。

方法:

Object postProcessBeforeInitialization(Object bean, String beanName)
Object postProcessAfterInitialization(Object bean, String beanName)

3.1 BeanPostProcessor 加载顺序

排序规则:

优先级 接口 说明
1 PriorityOrdered 最高优先级
2 Ordered 次级
3 普通 BeanPostProcessor 最后执行

Mermaid 展示顺序:

扫描所有 BeanPostProcessor
PriorityOrdered
Ordered
无序 BeanPostProcessor

3.2 BeanPostProcessor 与 AOP 的关系

AOP 是通过 AbstractAutoProxyCreator 生成代理对象,位于 postProcessAfterInitialization 阶段:

public Object postProcessAfterInitialization(Object bean, String beanName) {
    return wrapIfNecessary(bean, beanName);
}

AOP 代理是通过 BeanPostProcessor 创建的,而不是通过 XML 或注解直接生成。


4. 常用 BeanPostProcessor 源码解析

4.1 AutowiredAnnotationBeanPostProcessor

处理:

  • @Autowired
  • @Value
  • 构造器注入
public PropertyValues postProcessProperties(...) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, clazz, pvs);
    metadata.inject(bean, beanName, pvs);
    return pvs;
}

执行时机:populateBean 之前(属于 InstantiationAwareBeanPostProcessor)。


4.2 CommonAnnotationBeanPostProcessor

处理 JSR-250 注解:

  • @PostConstruct
  • @PreDestroy
  • @Resource

源码片段:

public Object postProcessBeforeInitialization(Object bean, String beanName) {
    invokeInitMethods(bean);
    return bean;
}

4.3 ApplicationContextAwareProcessor

处理:

  • ApplicationContextAware
  • BeanFactoryAware
  • EnvironmentAware

执行时机:initializeBean 阶段最早执行。

if (bean instanceof ApplicationContextAware) {
    ((ApplicationContextAware) bean).setApplicationContext(...)
}

4.4 AbstractAutoProxyCreator(AOP 的幕后角色)

负责生成代理对象,核心方法:

protected Object wrapIfNecessary(Object bean, String beanName) {
    if (bean 需要代理) {
        return createProxy(bean, beanName);
    }
    return bean;
}

5. Aware 与初始化体系

5.1 Aware 接口体系

Aware 接口 注入对象
BeanNameAware Bean 名称
BeanFactoryAware BeanFactory
ApplicationContextAware ApplicationContext
EnvironmentAware Environment
ResourceLoaderAware ResourceLoader

5.2 InitializingBean

public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() {
        // 初始化
    }
}

调用位置:

invokeInitMethods(beanName, bean, mbd)

5.3 @PostConstruct

优先级高于 InitializingBean。

顺序:

顺序 初始化方式
1 @PostConstruct
2 afterPropertiesSet
3 init-method(XML或@Bean)

6. 实战:自定义一个 BeanPostProcessor

统计每个 Bean 的初始化耗时,输出慢 Bean 警告。

@Component
public class CostTimeBeanPostProcessor implements BeanPostProcessor {

    private Map<String, Long> startTime = new ConcurrentHashMap<>();

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        startTime.put(beanName, System.currentTimeMillis());
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        long cost = System.currentTimeMillis() - startTime.get(beanName);
        if (cost > 50) {
            System.out.println(beanName + " 初始化耗时: " + cost + "ms");
        }
        return bean;
    }
}

启动时效果:

dataSource 初始化耗时: 110ms
entityManagerFactory 初始化耗时: 320ms

7. 如何调试 Bean 生命周期

7.1 打印完整生命周期

populateBeaninitializeBean处打断点。

7.2 打印所有 BeanPostProcessor

@Autowired
List<BeanPostProcessor> processors;

@PostConstruct
public void print() {
    processors.forEach(p -> System.out.println(p.getClass()));
}

7.3 使用 Spring Boot Actuator

访问:

/actuator/beans
/actuator/conditions

可查看所有 Bean 的创建链路。


8. 关键表格:生命周期、BPP、Aware、初始化执行顺序

8.1 生命周期执行顺序

步骤 说明
1 实例化 createBeanInstance()
2 属性填充 populateBean()
3 InstantiationAwareBPP
4 Aware 接口
5 BeanPostProcessor.beforeInit
6 @PostConstruct
7 InitializingBean
8 init-method
9 BeanPostProcessor.afterInit
10 Bean 就绪

8.2 常见后置处理器执行顺序

类型 执行阶段 示例
InstantiationAwareBeanPostProcessor 属性注入前 AutowiredAnnotationBeanPostProcessor
BeanPostProcessor Before 初始化前 ApplicationContextAwareProcessor
BeanPostProcessor After 初始化后 AOP 创建代理

结束语


👨‍💻 关于我

持续学习 | 追求真我

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

感谢订阅专栏 三连文章

image-20251011155556997

掘金点击访问Qiuner CSDN点击访问Qiuner GitHub点击访问Qiuner Gitee点击访问Qiuner

专栏 简介
📊 一图读懂系列 图文并茂,轻松理解复杂概念
📝 一文读懂系列 深入浅出,全面解析技术要点
🌟持续更新 保持学习,不断进步
🎯 人生经验 经验分享,共同成长

你好,我是Qiuner. 为帮助别人少走弯路而写博客

如果本篇文章帮到了你 不妨点个吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍

如果你遇到了问题,自己没法解决,可以去我掘金评论区问。CSDN评论区和私信消息看不完 掘金消息少一点.

上一篇推荐 链接
Java程序员快又扎实的学习路线 点击该处自动跳转查看哦
一文读懂 AI 点击该处自动跳转查看哦
一文读懂 服务器 点击该处自动跳转查看哦
2024年创作回顾 点击该处自动跳转查看哦
一文读懂 ESLint配置 点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑 点击该处自动跳转查看哦
未来会写什么文章? 预告链接
一文读懂 XX? 点击该处自动跳转查看哦
2025年终总结 点击该处自动跳转查看哦
一图读懂 XX? 点击该处自动跳转查看哦

img

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务

更多推荐