🤯 前言:面试官为什么要问这个?
“请你讲一下 Spring Bean 的生命周期。”
当面试官抛出这个问题时,他考的不是你的背诵能力,而是你对Spring 扩展点的理解。
- AOP 是在哪里介入的?
- 循环依赖是怎么解决的?
@Autowired是什么时候注入的?
如果你只能回答init和destroy,那只能拿 30 分。
今天,我们把 Spring 源码扒光,总结出标准的 12 个关键步骤。记住这张图,面试时直接在白板上画出来,稳拿 Offer!
🗺️ 上帝视角:生命周期全景图
Spring Bean 的生命周期本质上就是:创建 -> 属性赋值 -> 初始化 -> 使用 -> 销毁。
但在“初始化”阶段,Spring 埋下了大量的钩子 (Hooks)。
核心流程 Mermaid 图解:
📝 深度拆解:这 12 步到底在干嘛?
我们将这 12 步分为四个阶段,方便记忆。
第一阶段:无中生有 (实例化)
1. Instantiation (实例化)
- 动作:Spring 调用构造函数(
Constructor)或者工厂方法。 - 状态:此时的对象只是一个“空壳子”,所有属性都是 null,依赖还没有注入。
第二阶段:填充血肉 (属性赋值)
2. Populate Properties (属性赋值)
- 动作:Spring 将依赖的对象注入进来(DI)。
- 细节:处理
@Autowired、@Value等注解,或者 XML 中的<property>。
第三阶段:自我意识觉醒 (Aware 接口)
Bean 开始“认识”自己所处的环境。
3. BeanNameAware
- 喊话:“把我的名字(id)告诉我!”
4. BeanFactoryAware - 喊话:“把造我的工厂(BeanFactory)给我!”
5. ApplicationContextAware - 喊话:“把整个容器上下文(ApplicationContext)给我!”
第四阶段:初始化 (最重要!扩展点核心)
6. BeanPostProcessor - Before (前置处理)
- 核心:
postProcessBeforeInitialization - 作用:这是 AOP 和动态代理可能介入的第一个时机。你可以对 Bean 进行修改或替换。
7. @PostConstruct
- 来源:JSR-250 注解。
- 地位:执行顺序优先于接口和 XML 配置。
8. InitializingBean
- 动作:调用
afterPropertiesSet()方法。 - 场景:这是硬编码方式的初始化逻辑。
9. init-method
- 来源:XML
<bean init-method="...">或@Bean(initMethod = "...")。 - 特点:解耦,不需要实现 Spring 的接口。
10. BeanPostProcessor - After (后置处理)
- 核心:
postProcessAfterInitialization - 重中之重:AOP 动态代理通常是在这一步完成的!如果需要代理,这里返回的就不是原始 Bean,而是 Proxy 对象。
第五阶段:销毁 (落叶归根)
11. DisposableBean
- 动作:调用
destroy()接口。
12. destroy-method
- 动作:调用自定义销毁方法。
💻 代码实证:口说无凭,Run 一下
我们将所有接口都实现,看看控制台打印的顺序是否一致。
@ComponentpublicclassLifeCycleBeanimplementsBeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean{publicLifeCycleBean(){System.out.println("1. 构造函数 (Instantiation)");}@AutowiredpublicvoidsetService(SomeServiceservice){System.out.println("2. 属性赋值 (Populate Properties)");}@OverridepublicvoidsetBeanName(Stringname){System.out.println("3. BeanNameAware");}@OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){System.out.println("4. BeanFactoryAware");}@PostConstructpublicvoidpostConstruct(){System.out.println("7. @PostConstruct");}@OverridepublicvoidafterPropertiesSet(){System.out.println("8. InitializingBean");}publicvoidinitMethod(){System.out.println("9. init-method");}@Overridepublicvoiddestroy(){System.out.println("11. DisposableBean");}publicvoiddestroyMethod(){System.out.println("12. destroy-method");}}控制台输出结果:
(注:步骤 5, 6, 10 需要实现额外的 Processor 才会显示)
1. 构造函数 (Instantiation) 2. 属性赋值 (Populate Properties) 3. BeanNameAware 4. BeanFactoryAware (ApplicationContextAware...) (BeanPostProcessor - Before...) 7. @PostConstruct 8. InitializingBean 9. init-method (BeanPostProcessor - After...) ... 容器关闭 ... 11. DisposableBean 12. destroy-method🧠 记忆口诀 (面试必杀)
为了防止背了忘,请记住这个**“四字真言”**流程:
建 -> 填 -> 觉 -> 初 -> 销
- 建:实例化 (Constructor)
- 填:填属性 (Setter)
- 觉:觉醒 (Aware 接口)
- 初:初始化 (BPP Before -> Init -> BPP After)
- 销:销毁 (Destroy)
最关键的点:记住BeanPostProcessor像两个括号一样,包裹了所有的“初始化方法”。