Spring Bean生命周期全解:从下单链路拆解三种口径与BeanPostProcessor

发布时间:2026/10/31 8:50:21
Spring Bean生命周期全解:从下单链路拆解三种口径与BeanPostProcessor

项目标题是 Spring Bean 生命周期,我打算按“下单链路”来组织:先把三种说法的刻度对齐,再逐层拆开每一步在源码里的落点,最后用踩坑和探针工程收尾。开头会从一个反直觉的现象切入,避免教科书式引入。


面试被问到 Spring Bean 生命周期,十个人里有八个会条件反射地背:“实例化、属性赋值、初始化、使用、销毁”。背得滚瓜烂熟,一旦线上出问题,这套口诀立刻失灵。我印象很深的一次,某电商项目的下单接口在压测时偶发空指针,堆栈指到一个在@PostConstruct里赋过值的字段。按“五步法”的顺序推,初始化在属性赋值之后,字段不该是空的。实际排查下来,问题出在一个自定义BeanPostProcessor的返回值上,它把整条属性填充流程给跳过了——而这部分内容,五步法里根本没有位置安放。

所以这篇不讲“标准答案”,讲一件更实用的事:五步、七步、十步这三种流传很广的口径,本质是同一条流水线的三种颗粒度切法。我会用一个完整的“用户下单”场景把它们串起来——OrderController接请求,OrderService编排,InventoryService扣库存,PaymentGateway走支付,OrderCache做本地缓存,TraceContext记录链路 ID。这六个 Bean 各自的依赖关系、Aware 回调、代理生成、销毁释放,刚好能把生命周期里所有容易被忽略的节点都覆盖到。

适合谁看:写过 Spring 业务代码但对容器内部只有模糊印象的同学;被面试官追问“BeanPostProcessor 到底在哪一步执行”卡住过的同学;以及正在排查“注入为空”“事务不生效”“销毁方法没调用”这类问题的同学。看完你不需要再背顺序,因为每个节点都能对应到下单链路上一个具体的动作。

1. 三种口径争的是刻度粗细,不是谁对谁错

1.1 把创建 Bean 想成一条汽车装配线

很多人背生命周期背得痛苦,是把“步骤”当成了互不相干的独立事件。换个视角:Bean 的创建过程更像汽车总装线,每个工位只做一件事,做完推到下一个工位,中间还有几个质检员可以随时叫停或者改装。

原材料是BeanDefinition——它在容器启动时就已经从配置类、注解、XML 里解析出来了,记录着这个 Bean 叫什么、什么类型、单例还是多例、有哪些依赖、初始化方法是谁。真正的流水线从AbstractAutowireCapableBeanFactory#doCreateBean开始,这个方法内部就三步:createBeanInstance(焊车身,把对象 new 出来)、populateBean(装内饰,把依赖注入进去)、initializeBean(通电自检,跑初始化回调)。出厂之后进入使用期,容器关闭时走销毁工位。

所谓五步、七步、十步,就是在这条线上画的刻度线密度不同。五步法只在主干上标了五个大站,七步法把“自检”这一段拆细了,十步法连“车还没上流水线之前”的前置拦截都算进去了。它们不是三套不同的流程,而是同一套流程的三种注释详略。理解了这一点,“到底该背几