说下 Spring Bean 的生命周期?从实例化到销毁的完整旅程
说下 Spring Bean 的生命周期从实例化到销毁的完整旅程1. 先看结论速记版2. 完整生命周期流程图3. 生命周期详细解析3.1 第一阶段实例化Instantiation3.2 第二阶段属性填充Population3.3 第三阶段初始化前Before Initialization3.4 第四阶段初始化Initialization3.5 第五阶段初始化后After Initialization3.6 第六阶段使用In Use3.7 第七阶段销毁Destruction4. 完整代码示例贯穿整个生命周期5. 各扩展点对比表5.1 初始化阶段对比5.2 销毁阶段对比6. 常见面试追问Q1AOP 代理在哪个阶段生成Q2为什么 AOP 不能在更早的阶段生成Q3PostConstruct 和 afterPropertiesSet 有什么区别Q4如果一个 Bean 既实现了 InitializingBean 又指定了 init-method执行顺序Q5BeanPostProcessor 和 BeanFactoryPostProcessor 的区别7. 生命周期中的设计模式8. 记忆口诀9. 思考题The Begin点点关注收藏不迷路⬇ ⬇ 底部 ⬇ ⬇Spring Bean 的生命周期是面试中的“核弹级”问题也是理解 Spring 框架的核心钥匙。本文将按照时间顺序从 Bean 的创建到销毁完整讲解每个阶段的核心方法、扩展点和底层原理。1. 先看结论速记版阶段核心动作关键扩展点1. 实例化调用构造器创建对象BeanPostProcessor前置2. 属性填充注入依赖AutowiredInstantiationAwareBeanPostProcessor3. 初始化前Bean 初始化前回调PostConstruct、BeanPostProcessor.postProcessBeforeInitialization4. 初始化执行自定义初始化InitializingBean.afterPropertiesSet()、Bean(initMethod)5. 初始化后Bean 初始化后回调BeanPostProcessor.postProcessAfterInitialization、AOP 代理生成6. 使用正常运行业务调用7. 销毁销毁前回调PreDestroy、DisposableBean.destroy()、Bean(destroyMethod)一句话总结构造器 → 注入属性 → 初始化前 → 初始化 → 初始化后 → 使用 → 销毁2. 完整生命周期流程图渲染错误:Mermaid 渲染失败: Parse error on line 14: ...tion] F -- G[PostConstruct 方法执 ----------------------^ Expecting AMP, COLON, PIPE, TESTSTR, DOWN, DEFAULT, NUM, COMMA, NODE_STRING, BRKT, MINUS, MULT, UNICODE_TEXT, got LINK_ID3. 生命周期详细解析3.1 第一阶段实例化Instantiation时机容器启动根据BeanDefinition创建 Bean 实例核心动作通过构造器或工厂方法创建对象此时对象属性全为默认值null/0/false只是分配了内存空间ComponentpublicclassUserService{privateStringname;// 此时为 null// 实例化时调用构造器publicUserService(){System.out.println(1. 实例化执行构造器);}}关键扩展点ComponentpublicclassMyInstantiationAwareBeanPostProcessorimplementsInstantiationAwareBeanPostProcessor{OverridepublicObjectpostProcessBeforeInstantiation(Class?beanClass,StringbeanName){// 实例化前回调可返回代理对象替换原始 Beanif(beanName.equals(userService)){System.out.println(实例化前可以返回代理对象);}returnnull;// 返回 null 表示正常实例化}}3.2 第二阶段属性填充Population时机对象实例化后注入依赖核心动作Autowired、Value、Resource等注解注入XML 配置的property注入Aware 接口注入BeanNameAware、ApplicationContextAware 等ComponentpublicclassUserServiceimplementsBeanNameAware,ApplicationContextAware{AutowiredprivateOrderServiceorderService;// 依赖注入privateStringbeanName;privateApplicationContextapplicationContext;OverridepublicvoidsetBeanName(Stringname){this.beanNamename;System.out.println(2. 属性填充BeanNameAware - name);}OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){this.applicationContextapplicationContext;System.out.println(2. 属性填充ApplicationContextAware);}}关键 Aware 接口执行顺序Aware 接口注入内容执行时机BeanNameAwareBean 在容器中的名称属性填充后BeanClassLoaderAware类加载器属性填充后BeanFactoryAwareBeanFactory 实例属性填充后ApplicationContextAwareApplicationContext属性填充后EnvironmentAwareEnvironment 配置属性填充后ResourceLoaderAwareResourceLoader属性填充后3.3 第三阶段初始化前Before Initialization时机属性填充完成后执行自定义初始化逻辑之前核心动作BeanPostProcessor.postProcessBeforeInitialization()PostConstruct标注的方法ComponentpublicclassUserService{PostConstructpublicvoidinit(){System.out.println(3. 初始化前PostConstruct 方法执行);}}// 或通过 BeanPostProcessorComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofUserService){System.out.println(3. 初始化前BeanPostProcessor.before);}returnbean;}}执行顺序1.BeanPostProcessor.postProcessBeforeInitialization()2.PostConstruct标注的方法3.4 第四阶段初始化Initialization时机执行自定义初始化逻辑核心动作InitializingBean.afterPropertiesSet()自定义init-method如Bean(initMethodmyInit)ComponentpublicclassUserServiceimplementsInitializingBean{OverridepublicvoidafterPropertiesSet()throwsException{System.out.println(4. 初始化InitializingBean.afterPropertiesSet);}// 自定义初始化方法publicvoidmyCustomInit(){System.out.println(4. 初始化自定义 init-method);}}// 配置类中指定ConfigurationpublicclassAppConfig{Bean(initMethodmyCustomInit)publicUserServiceuserService(){returnnewUserService();}}执行顺序1.InitializingBean.afterPropertiesSet()2.自定义 init-method3.5 第五阶段初始化后After Initialization时机初始化完成后Bean 正式可用的最后一道工序核心动作BeanPostProcessor.postProcessAfterInitialization()AOP 代理生成关键ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(beaninstanceofUserService){System.out.println(5. 初始化后BeanPostProcessor.after);// 这里可以返回代理对象替换原 Bean// 例如AOP 在这里生成代理}returnbean;}}AOP 代理生成时机// AbstractAutoProxyCreator 是 BeanPostProcessor 的实现publicclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){// 检查是否需要 AOP 代理if(beaninstanceofAdvised){returnbean;}// 如果需要代理返回代理对象returnwrapIfNecessary(bean,beanName);}}3.6 第六阶段使用In Use时机Bean 完全初始化完毕放入singletonObjects一级缓存ServicepublicclassOrderService{AutowiredprivateUserServiceuserService;// 使用已初始化完成的 BeanpublicvoiddoSomething(){userService.sayHello();// 正常业务调用}}3.7 第七阶段销毁Destruction时机容器关闭时核心动作PreDestroy标注的方法DisposableBean.destroy()自定义destroy-methodComponentpublicclassUserServiceimplementsDisposableBean{PreDestroypublicvoidpreDestroy(){System.out.println(7. 销毁前PreDestroy 执行);}Overridepublicvoiddestroy()throwsException{System.out.println(7. 销毁DisposableBean.destroy);}publicvoidmyCustomDestroy(){System.out.println(7. 销毁自定义 destroy-method);}}// 配置类ConfigurationpublicclassAppConfig{Bean(destroyMethodmyCustomDestroy)publicUserServiceuserService(){returnnewUserService();}}执行顺序1.PreDestroy标注的方法2.DisposableBean.destroy()3.自定义 destroy-method4. 完整代码示例贯穿整个生命周期ComponentpublicclassLifecycleDemoimplementsBeanNameAware,BeanClassLoaderAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{privateStringname;AutowiredprivateOrderServiceorderService;// 1. 实例化 publicLifecycleDemo(){System.out.println(【1】实例化构造器执行);}// 2. 属性填充 AutowiredpublicvoidsetName(Value(testBean)Stringname){this.namename;System.out.println(【2】属性填充Value 注入 name name);}OverridepublicvoidsetBeanName(Stringname){System.out.println(【2】属性填充BeanNameAware - name);}OverridepublicvoidsetBeanClassLoader(ClassLoaderclassLoader){System.out.println(【2】属性填充BeanClassLoaderAware);}OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{System.out.println(【2】属性填充BeanFactoryAware);}OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{System.out.println(【2】属性填充ApplicationContextAware);}// 3. 初始化前 PostConstructpublicvoidpostConstruct(){System.out.println(【3】初始化前PostConstruct 执行);}// 4. 初始化 OverridepublicvoidafterPropertiesSet()throwsException{System.out.println(【4】初始化InitializingBean.afterPropertiesSet 执行);}// 自定义 init-method需在 Bean 中指定publicvoidcustomInit(){System.out.println(【4】初始化自定义 init-method 执行);}// 5. 初始化后 // BeanPostProcessor.postProcessAfterInitialization 会在这里执行// 6. 使用 publicvoiddoWork(){System.out.println(【6】使用业务方法执行);}// 7. 销毁 PreDestroypublicvoidpreDestroy(){System.out.println(【7】销毁前PreDestroy 执行);}Overridepublicvoiddestroy()throwsException{System.out.println(【7】销毁DisposableBean.destroy 执行);}publicvoidcustomDestroy(){System.out.println(【7】销毁自定义 destroy-method 执行);}}// 配置类ConfigurationpublicclassLifecycleConfig{Bean(initMethodcustomInit,destroyMethodcustomDestroy)publicLifecycleDemolifecycleDemo(){returnnewLifecycleDemo();}}// BeanPostProcessor 示例ComponentpublicclassCustomBeanPostProcessorimplementsBeanPostProcessor{OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleDemo){System.out.println(【3】初始化前BeanPostProcessor.before);}returnbean;}OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(beaninstanceofLifecycleDemo){System.out.println(【5】初始化后BeanPostProcessor.after);}returnbean;}}运行输出【1】实例化构造器执行 【2】属性填充Value 注入 name testBean 【2】属性填充BeanNameAware - lifecycleDemo 【2】属性填充BeanClassLoaderAware 【2】属性填充BeanFactoryAware 【2】属性填充ApplicationContextAware 【3】初始化前BeanPostProcessor.before 【3】初始化前PostConstruct 执行 【4】初始化InitializingBean.afterPropertiesSet 执行 【4】初始化自定义 init-method 执行 【5】初始化后BeanPostProcessor.after 【6】使用业务方法执行 【7】销毁前PreDestroy 执行 【7】销毁DisposableBean.destroy 执行 【7】销毁自定义 destroy-method 执行5. 各扩展点对比表5.1 初始化阶段对比扩展方式执行阶段执行顺序使用场景InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation实例化前1返回代理对象替换原 BeanBeanPostProcessor.postProcessBeforeInitialization初始化前2对所有 Bean 做统一处理PostConstruct初始化前3Bean 自己的初始化逻辑InitializingBean.afterPropertiesSet初始化4实现接口做初始化Bean(initMethod)初始化5不侵入代码的初始化BeanPostProcessor.postProcessAfterInitialization初始化后6AOP 代理生成、数据校验5.2 销毁阶段对比扩展方式执行阶段使用场景PreDestroy销毁前释放资源DisposableBean.destroy销毁实现接口做清理Bean(destroyMethod)销毁不侵入代码的清理6. 常见面试追问Q1AOP 代理在哪个阶段生成答在BeanPostProcessor.postProcessAfterInitialization阶段。Spring 的AbstractAutoProxyCreator实现了这个接口在初始化后检查 Bean 是否需要代理如果需要则返回代理对象替换原始 Bean。Q2为什么 AOP 不能在更早的阶段生成答因为需要等待依赖注入完成需要等待PostConstruct等初始化完成代理对象需要持有原始 Bean 的所有状态Q3PostConstruct和afterPropertiesSet有什么区别对比PostConstructafterPropertiesSet标准JSR-250 标准Spring 专有执行时机更早稍晚依赖注入已完成已完成推荐度✅ 推荐⚠️ Spring 耦合Q4如果一个 Bean 既实现了InitializingBean又指定了init-method执行顺序答afterPropertiesSet()先执行init-method后执行。// 执行顺序// 1. afterPropertiesSet()// 2. init-methodQ5BeanPostProcessor 和 BeanFactoryPostProcessor 的区别对比BeanPostProcessorBeanFactoryPostProcessor作用对象Bean 实例BeanDefinition执行时机Bean 实例化后Bean 实例化前典型应用AOP、Autowired配置属性替换PropertySource7. 生命周期中的设计模式设计模式应用场景源码体现模板方法模式定义 Bean 创建流程AbstractAutowireCapableBeanFactory.doCreateBean()工厂模式创建 Bean 实例BeanFactory、FactoryBean策略模式不同实例化策略InstantiationStrategy观察者模式容器事件监听ApplicationListener责任链模式BeanPostProcessor 链ListBeanPostProcessor8. 记忆口诀实例化先调构造属性填充依赖到Aware 接口注资源PostConstruct 前奏绕afterPropertiesSet 走init-method 后续搞后置处理 AOP 生Bean 就绪业务跑容器关闭要销毁PreDestroy 最后扫9. 思考题// 问题以下代码的执行顺序是什么ComponentpublicclassTestBeanimplementsInitializingBean,BeanPostProcessor{publicTestBean(){System.out.println(1);}PostConstructpublicvoidpost(){System.out.println(2);}OverridepublicvoidafterPropertiesSet(){System.out.println(3);}OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){System.out.println(4);returnbean;}OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){System.out.println(5);returnbean;}}答案1 // 实例化 4 // 其他 Bean 初始化时会触发但不会自己触发自己 2 // PostConstruct 3 // afterPropertiesSet 5 // postProcessAfterInitialization注意BeanPostProcessor 自身也会被容器作为 Bean 处理但它的执行时机是在其他 Bean 的初始化过程中不是在自己初始化过程中调用自己的方法。希望这篇文章能帮你彻底掌握 Spring Bean 的生命周期。如果觉得有用欢迎点赞、收藏、转发 关注我更多 Spring 源码干货持续更新中。The End点点关注收藏不迷路⬆ ⬆ 顶部 ⬆ ⬆