)
Spring源码全套连载系列持续更新前面六篇我们铺垫完了Spring容器架构、IoC思想、Refresh刷新流程、BeanDefinition、两大后置处理器核心原理。所有铺垫全部完成今天正式击穿Spring源码最核心、面试最高频、开发最常用的知识点Bean完整生命周期。很多开发者工作三五年只会背生命周期步骤却完全不懂Bean到底是何时实例化、何时赋值、何时初始化构造方法、Autowired、PostConstruct、InitializingBean执行顺序为什么是固定的AOP代理到底插在生命周期的哪一步三级缓存循环依赖是在哪个阶段生效Bean销毁的触发时机和底层逻辑是什么本篇带你从零到一、逐阶段、逐源码拆解Bean完整生命周期打通Spring Bean从诞生、赋值、初始化、增强、使用、销毁的全链路彻底告别死记硬背一、前置核心认知1.1 生命周期触发时机回顾refresh()十二大流程Bean生命周期的所有核心步骤全部集中在步骤11 finishBeanFactoryInitialization初始化所有非懒加载单例Bean。前面所有步骤都是准备工作这一步才是Bean真正诞生的核心阶段。1.2 完整生命周期总览先记骨架Spring Bean完整生命周期一共10大核心阶段顺序绝对固定加载解析 - 实例化 - 构造方法执行 - 属性填充依赖注入 - 初始化前置处理 - 自定义初始化方法 - Bean后置增强AOP - 存入单例池 - 正常使用 - 容器关闭销毁1.3 核心结论BeanDefinition是图纸生命周期是施工流程单例池是成品仓库。二、Bean生命周期十步完整源码拆解超详细我们以单例、非懒加载、普通业务Bean为例全程跟进源码逐阶段解析第一步Bean定义加载图纸备案对应阶段refresh()第5步invokeBeanFactoryPostProcessors核心操作通过ConfigurationClassPostProcessor扫描包路径解析Component、Service、Bean等注解将Java类封装为BeanDefinition元数据注册到beanDefinitionMap容器中当前状态只有Bean图纸没有Bean实例不占用堆内存第二步Bean实例化对象诞生对应源码createBean()-doCreateBean()-createBeanInstance()核心操作Spring根据BeanDefinition获取Bean的Class对象通过反射机制调用无参/有参构造方法创建出Bean的原生空对象关键特点此时的Bean仅仅是一个空对象所有属性都是默认值、未完成依赖注入还不能使用重点循环依赖的三级缓存在这一步提前曝光Bean对象。第三步属性填充依赖注入对应源码populateBean()这一步是Autowired、Resource生效的核心阶段核心操作扫描当前Bean所有属性字段通过AutowiredAnnotationBeanPostProcessor解析Autowired通过CommonAnnotationBeanPostProcessor解析Resource从容器单例池中获取依赖Bean完成属性赋值、依赖注入执行结果Bean内部所有依赖对象全部填充完成属性完整。第四步初始化前置处理Before对应源码initializeBean()-applyBeanPostProcessorsBeforeInitialization()核心操作遍历所有BeanPostProcessor执行postProcessBeforeInitialization前置方法经典场景PostConstruct 注解方法在这里执行很多人混淆顺序PostConstruct 早于 InitializingBean。第五步Bean初始化方法执行这一步包含两个层级的初始化执行顺序固定1、执行Spring内置初始化接口执行InitializingBean#afterPropertiesSet()方法Spring内置接口属性填充完成后自动触发。2、执行自定义初始化方法执行BeanDefinition中配置的init-method自定义初始化方法。执行顺序总结PostConstruct afterPropertiesSet init-method第六步初始化后置处理AOP代理对应源码applyBeanPostProcessorsAfterInitialization()这是整个生命周期的超级核心AOP代理诞生地核心操作遍历所有Bean后置处理器执行postProcessAfterInitialization后置方法AnnotationAwareAspectJAutoProxyCreator介入判断当前Bean是否需要切面增强需要增强则创建JDK动态代理 / Cglib代理用代理对象替换原生Bean对象颠覆性认知我们最终使用的Bean不一定是自己new的原生对象而是Spring替换后的代理对象AOP、事务全部依赖这一步实现。第七步Bean存入单例池对应源码addSingleton()核心操作将完整初始化、可能已被代理增强的Bean对象存入Spring核心单例池singletonObjects关键特性一旦存入单例池全局唯一、复用终生后续所有依赖获取的都是这同一个对象。第八步Bean就绪对外提供服务容器启动完成Bean完全就绪属性填充完毕初始化完成代理增强完成存入单例池此时可以正常接收请求、执行业务逻辑。第九步Bean销毁阶段触发时机Spring容器关闭、销毁时执行顺序执行PreDestroy注解方法执行DisposableBean#destroy()接口方法执行自定义destroy-method销毁方法用于资源释放、连接关闭、缓存清理等收尾操作。三、生命周期执行顺序终极汇总必背整理全网最标准、最全的执行顺序面试直接满分1. 构造方法实例化→2. 属性填充Autowired/Resource→3. PostConstruct→4. InitializingBean后置初始化→5. 自定义init方法→6. AOP代理增强→7. 存入单例池使用→8. 容器关闭执行销毁方法四、高频易错点深度答疑解决90%困惑4.1 为什么PostConstruct在init方法之前因为PostConstruct属于Bean后置处理器的前置阶段执行是Spring注解层面的初始化而InitializingBean和init-method是Bean完整属性填充后的底层初始化执行层级靠后。4.2 AOP为什么必须在初始化之后执行AOP是对完整可用Bean的增强必须保证Bean实例化完成、属性注入完成、初始化完成确保代理的是一个完整、无缺陷的Bean对象避免代理半成品对象导致异常。4.3 循环依赖和生命周期的关系循环依赖生效在实例化阶段Spring提前将半成品Bean放入三级缓存提前曝光对象引用解决互相依赖问题不会影响后续属性填充、初始化、代理流程。4.4 单例Bean和多例Bean生命周期区别单例Bean容器启动统一创建、初始化、存入单例池容器销毁才销毁全局唯一多例Bean每次获取才创建容器不管理、不缓存、不销毁用完即废五、完整生命周期代码演示直观验证手写代码直观看到所有阶段执行顺序彻底固化认知Service public class UserService implements InitializingBean, DisposableBean { Autowired private UserDao userDao; // 1. 构造方法实例化 public UserService() { System.out.println(1、Bean构造方法实例化); } // 2. 属性注入完成 // 3. 注解初始化 PostConstruct public void postConstruct() { System.out.println(3、执行PostConstruct初始化方法); } // 4. Spring内置初始化接口 Override public void afterPropertiesSet() throws Exception { System.out.println(4、执行InitializingBean afterPropertiesSet); } // 5. 自定义初始化方法 public void initMethod() { System.out.println(5、执行自定义init-method初始化); } // 销毁方法 PreDestroy public void preDestroy() { System.out.println(容器关闭执行PreDestroy销毁方法); } Override public void destroy() throws Exception { System.out.println(容器关闭执行DisposableBean销毁方法); } }执行结果完全贴合我们上面梳理的生命周期顺序无任何偏差。六、面试满分题库本篇专属1、简单说一下Spring Bean的完整生命周期首先容器启动后扫描解析类生成BeanDefinition注册到容器随后通过反射实例化Bean空对象完成属性依赖注入接着执行PostConstruct注解初始化方法、InitializingBean初始化方法、自定义init方法之后通过Bean后置处理器完成AOP代理增强将完整Bean存入单例池对外提供服务最后在容器关闭时执行PreDestroy、DisposableBean、自定义销毁方法完成资源释放。2、Bean初始化相关方法的执行顺序构造方法实例化 → 属性注入 → PostConstruct → InitializingBean#afterPropertiesSet → 自定义init-method。3、AOP代理是在Bean生命周期的哪个阶段创建在Bean初始化完成之后执行BeanPostProcessor的postProcessAfterInitialization方法阶段由AnnotationAwareAspectJAutoProxyCreator完成动态代理对象的创建与替换。4、Bean实例化和初始化的区别实例化是通过反射创建空的Bean对象仅仅开辟内存初始化是在对象创建、属性填充完成后执行各类初始化方法、完成代理增强让Bean成为一个完整可用的业务对象。5、单例Bean什么时候创建、什么时候销毁非懒加载单例Bean在容器刷新finishBeanFactoryInitialization阶段统一创建在Spring容器关闭时统一执行销毁逻辑、释放资源。七、本篇总结下期预告本篇总结本篇我们彻底吃透了Spring Bean完整生命周期打通了IoC容器最核心的执行链路掌握了Bean从定义、实例化、赋值、初始化、增强、销毁的10大完整阶段彻底理清了各类初始化方法的固定执行顺序搞懂了AOP代理、循环依赖在生命周期中的位置区分了实例化与初始化的本质区别汇总了面试高频满分答案彻底告别背诵记忆下期预告下一篇我们攻克Spring最大难点、面试终极压轴题三级缓存彻底解决Bean循环依赖源码全解全网最通俗拆解搞定90%程序员搞不懂的循环依赖原理 往期推荐 系列连载本系列持续更新全程干货无水文关注我带你从零吃透Spring源码彻底搞定面试底层原理