Spring Bean生命周期
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
Spring Bean的生命周期,本质是Bean从被容器识别定义到容器关闭销毁的全流程,核心围绕IOC容器的实例化、依赖注入、初始化、销毁四大核心逻辑展开。整个过程可通过容器扩展接口、注解灵活定制,是Spring框架控制反转、依赖注入特性的核心体现,也是面试和实战中必须掌握的底层原理。
一、Bean生命周期核心阶段总览
标准生命周期分为6大核心阶段,按执行顺序依次为:Bean定义加载与解析→Bean实例化→属性填充与依赖注入→初始化处理→业务使用→容器关闭与Bean销毁。其中初始化和销毁环节支持多层扩展回调,可灵活定制Bean的前置、后置逻辑。
二、完整生命周期分步拆解(按执行时序)
阶段1:Bean定义加载与解析
这是生命周期的起点,Spring容器启动后,会扫描并解析所有Bean的配置元信息,完成Bean的“身份登记”,暂不创建实例。
- 触发时机:Spring IOC容器(ApplicationContext/BeanFactory)初始化阶段
- 核心动作:解析XML配置、注解(@Component、@Service、@Bean等)、JavaConfig配置,将Bean的类路径、作用域、依赖关系、初始化/销毁方法等信息封装为BeanDefinition对象,存入BeanDefinitionRegistry注册表
- 关键说明:此阶段仅完成定义,未实例化对象,单例Bean和多例Bean的定义加载逻辑一致
阶段2:Bean实例化(Instantiation)
容器根据BeanDefinition创建Bean的裸实例对象,仅完成对象内存分配,未填充属性、未执行初始化逻辑,相当于Java中的new对象操作。
- 触发时机:单例Bean(默认scope=singleton)在容器启动时立即实例化;多例Bean(scope=prototype)在每次获取Bean(getBean)时才实例化
- 实例化方式:默认通过反射调用无参构造器实例化;支持自定义实例化策略(静态工厂方法、实例工厂方法、FactoryBean接口)
- 关键说明:实例化后的对象是“裸对象”,属性均为默认值(null、0等),尚未注入依赖
阶段3:属性填充与依赖注入(Population)
这是Spring依赖注入(DI)的核心环节,容器为实例化后的裸对象填充属性、注入依赖对象,完成对象属性的初始化赋值。
- 核心动作:通过setter方法、构造器注入、字段注入(@Autowired)、@Value注解等方式,为Bean的成员变量赋值;自动处理依赖Bean的循环注入、依赖排序
- 执行逻辑:容器先解析Bean的依赖关系,递归创建依赖的Bean实例,再将依赖对象注入当前Bean,保证依赖提前就绪
- 关键说明:此阶段完成后,Bean的基础属性和依赖已就绪,但未执行自定义初始化逻辑
阶段4:初始化处理(Initialization)
初始化是生命周期中最灵活的扩展环节,分为Aware接口回调、后置处理器前置处理、自定义初始化、后置处理器后置处理四步,按固定顺序执行,完成Bean的业务前置准备。
4.1 Aware接口感知回调
让Bean感知Spring容器的自身信息,获取容器内置对象,属于容器级别的回调。
- 常用Aware接口:BeanNameAware(获取Bean名称)、BeanFactoryAware(获取BeanFactory容器)、ApplicationContextAware(获取ApplicationContext上下文)、EnvironmentAware(获取环境配置)
- 执行逻辑:容器自动调用Bean实现的Aware接口方法,注入容器相关实例,无需手动触发
4.2 BeanPostProcessor前置处理
执行全局后置处理器的前置方法,对所有Bean统一做前置增强,是Spring AOP代理、事务代理生成的核心入口。
- 核心接口:BeanPostProcessor#postProcessBeforeInitialization(Object bean, String beanName)
- 作用:在自定义初始化前对Bean实例做修改、增强、包装,比如生成动态代理对象
4.3 自定义初始化回调(按顺序执行)
执行用户定制的初始化逻辑,三种方式按固定优先级执行,优先级从高到低:
- @PostConstruct注解:标注在方法上,最常用、最简洁的初始化方式
- InitializingBean接口:实现afterPropertiesSet()方法,底层接口方式
- init-method配置:XML配置init-method、@Bean(initMethod)指定自定义方法
4.4 BeanPostProcessor后置处理
执行全局后置处理器的后置方法,完成Bean的最终增强,AOP代理对象最终在此阶段生成。
- 核心接口:BeanPostProcessor#postProcessAfterInitialization(Object bean, String beanName)
- 关键说明:此阶段执行完毕后,Bean正式成为“就绪状态”,可被业务调用
阶段5:Bean业务使用(In Use)
初始化完成的Bean存入Spring容器缓存(单例Bean),供业务代码通过@Autowired、getBean()方式获取调用,这是Bean生命周期中最长的阶段,贯穿整个应用运行周期。
- 单例Bean:存入容器单例池,全局复用,直至容器关闭
- 多例Bean:每次获取创建新实例,使用后交由JVM垃圾回收,容器不管理其销毁
阶段6:容器关闭与Bean销毁(Destruction)
仅单例Bean会被容器管理销毁逻辑,多例Bean不参与此阶段;容器关闭时触发销毁回调,释放Bean占用的资源(如连接池、文件句柄等)。
6.1 销毁回调执行顺序(优先级从高到低)
- @PreDestroy注解:标注在方法上,优先执行
- DisposableBean接口:实现destroy()方法
- destroy-method配置:XML配置destroy-method、@Bean(destroyMethod)指定自定义销毁方法
6.2 触发时机
调用ApplicationContext#close()方法、应用正常停机(Web环境)时触发,容器依次销毁所有单例Bean,释放资源。
三、不同作用域Bean的生命周期差异
Bean的作用域直接影响生命周期的触发时机和管理逻辑,核心差异如下:
singleton(单例) | 容器启动时(默认) | 全局唯一,容器全程管理 | 容器关闭时执行销毁回调 |
prototype(多例) | 每次获取Bean时 | 容器仅负责创建,不缓存 | 不执行销毁回调,JVM GC回收 |
request/ session(Web) | 请求/会话创建时 | 绑定请求/会话生命周期 | 请求/会话结束时销毁 |
四、生命周期核心总结
Spring Bean生命周期可浓缩为一句口诀:先定义,再实例;注属性,知容器;前增强,初初始化;后增强,供使用;关容器,才销毁。整个流程由Spring容器全权控制,开发者通过Aware接口、BeanPostProcessor、初始化/销毁注解/接口,即可实现对Bean生命周期的精细化管控,是Spring框架扩展性的核心体现。
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
本专栏聚焦Spring全生态体系,从IoC/AOP核心原理入手,覆盖Spring Boot自动配置、事务管理、Web开发等实战内容。拆解循环依赖、动态代理等高频面试难点,助力开发者从入门到精通,打通单体到微服务的技术链路,解决企业级开发痛点,提升架构设计与问题排查能力,成为Java后端进阶的必备技术专栏。