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

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

文章目录

  • [Spring Boot 机制五: Bean 生命周期与后置处理器(BeanPostProcessor)源码深度剖析](#Spring Boot 机制五: Bean 生命周期与后置处理器(BeanPostProcessor)源码深度剖析)
  • 目录
  • [1. Bean 生命周期全景图](#1. Bean 生命周期全景图)
  • [2. Bean 创建的完整阶段(含详细源码)](#2. Bean 创建的完整阶段(含详细源码))
    • [2.1 核心入口:doCreateBean()](#2.1 核心入口:doCreateBean())
    • [2.2 Bean 实例化:createBeanInstance()](#2.2 Bean 实例化:createBeanInstance())
    • [2.3 属性填充:populateBean()](#2.3 属性填充:populateBean())
    • [2.4 初始化 initializeBean()](#2.4 初始化 initializeBean())
  • [3. BeanPostProcessor 原理与执行顺序](#3. BeanPostProcessor 原理与执行顺序)
    • [3.1 BeanPostProcessor 加载顺序](#3.1 BeanPostProcessor 加载顺序)
    • [3.2 BeanPostProcessor 与 AOP 的关系](#3.2 BeanPostProcessor 与 AOP 的关系)
  • [4. 常用 BeanPostProcessor 源码解析](#4. 常用 BeanPostProcessor 源码解析)
    • [4.1 AutowiredAnnotationBeanPostProcessor](#4.1 AutowiredAnnotationBeanPostProcessor)
    • [4.2 CommonAnnotationBeanPostProcessor](#4.2 CommonAnnotationBeanPostProcessor)
    • [4.3 ApplicationContextAwareProcessor](#4.3 ApplicationContextAwareProcessor)
    • [4.4 AbstractAutoProxyCreator(AOP 的幕后角色)](#4.4 AbstractAutoProxyCreator(AOP 的幕后角色))
  • [5. Aware 与初始化体系](#5. Aware 与初始化体系)
    • [5.1 Aware 接口体系](#5.1 Aware 接口体系)
    • [5.2 InitializingBean](#5.2 InitializingBean)
    • [5.3 @PostConstruct](#5.3 @PostConstruct)
  • [6. 实战:自定义一个 BeanPostProcessor](#6. 实战:自定义一个 BeanPostProcessor)
  • [7. 如何调试 Bean 生命周期](#7. 如何调试 Bean 生命周期)
    • [7.1 打印完整生命周期](#7.1 打印完整生命周期)
    • [7.2 打印所有 BeanPostProcessor](#7.2 打印所有 BeanPostProcessor)
    • [7.3 使用 Spring Boot Actuator](#7.3 使用 Spring Boot Actuator)
  • [8. 关键表格:生命周期、BPP、Aware、初始化执行顺序](#8. 关键表格:生命周期、BPP、Aware、初始化执行顺序)
    • [8.1 生命周期执行顺序](#8.1 生命周期执行顺序)
    • [8.2 常见后置处理器执行顺序](#8.2 常见后置处理器执行顺序)
  • 结束语

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 的创建最终都落到:

java 复制代码
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

核心代码:

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

2.3 属性填充:populateBean()

属性注入发生在这里:

java 复制代码
populateBean(beanName, mbd, instanceWrapper);

流程:

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

核心代码:

java 复制代码
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

核心代码:

java 复制代码
Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

3. BeanPostProcessor 原理与执行顺序

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

方法:

java 复制代码
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 阶段:

java 复制代码
public Object postProcessAfterInitialization(Object bean, String beanName) {
    return wrapIfNecessary(bean, beanName);
}

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


4. 常用 BeanPostProcessor 源码解析

4.1 AutowiredAnnotationBeanPostProcessor

处理:

  • @Autowired
  • @Value
  • 构造器注入
java 复制代码
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

源码片段:

java 复制代码
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    invokeInitMethods(bean);
    return bean;
}

4.3 ApplicationContextAwareProcessor

处理:

  • ApplicationContextAware
  • BeanFactoryAware
  • EnvironmentAware

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

java 复制代码
if (bean instanceof ApplicationContextAware) {
    ((ApplicationContextAware) bean).setApplicationContext(...)
}

4.4 AbstractAutoProxyCreator(AOP 的幕后角色)

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

java 复制代码
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

java 复制代码
public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() {
        // 初始化
    }
}

调用位置:

java 复制代码
invokeInitMethods(beanName, bean, mbd)

5.3 @PostConstruct

优先级高于 InitializingBean。

顺序:

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

6. 实战:自定义一个 BeanPostProcessor

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

java 复制代码
@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

java 复制代码
@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 创建代理

结束语

👨‍💻 关于我

持续学习 | 追求真我

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

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

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

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

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

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

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

上一篇推荐 链接
Java程序员快又扎实的学习路线 点击该处自动跳转查看哦
一文读懂 AI 点击该处自动跳转查看哦
一文读懂 服务器 点击该处自动跳转查看哦
2024年创作回顾 点击该处自动跳转查看哦
一文读懂 ESLint配置 点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑 点击该处自动跳转查看哦
未来会写什么文章? 预告链接
一文读懂 XX? 点击该处自动跳转查看哦
2025年终总结 点击该处自动跳转查看哦
一图读懂 XX? 点击该处自动跳转查看哦
相关推荐
路边草随风5 小时前
java实现发布flink yarn session模式作业
java·flink·yarn
qq_12498707535 小时前
基于Spring Boot的阳光餐盘点餐系统(源码+论文+部署+安装)
java·vue.js·spring boot·后端·毕业设计
程序员三明治5 小时前
【Java基础】序列化到底是什么?有什么用?实现原理?
java·开发语言·后端·java基础·序列化·反序列化
Full Stack Developme5 小时前
Java实现Word、Excel、PDF文件 在线预览
java·word·excel
武子康5 小时前
Java-185 Guava Cache 实战:删除策略、过期机制与常见坑全梳理
java·spring boot·redis·spring·缓存·guava·guava cache
阿杰同学5 小时前
Java 网络协议面试题答案整理,最新面试题
java·开发语言·网络协议
晨非辰5 小时前
C++ 波澜壮阔 40 年:引用、内联函数与现代空指针,效率跃升三基石
运维·c++·人工智能·后端·python·深度学习
CoderYanger5 小时前
动态规划算法-两个数组的dp(含字符串数组):41.最长公共子序列(模板)
java·算法·leetcode·动态规划·1024程序员节
凌波粒5 小时前
Springboot基础教程(8)--Shiro
java·spring boot·后端