bean 生命周期 概述
bean 的生命周期从调用 beanFactory 的 getBean 开始,到这个 bean 被销毁,可以总结为以下七个阶段:
1. 处理名称,检查缓存
2. 处理父子容器
3. 处理 dependsOn
4. 选择 scope 策略
5. 创建 bean
6. 类型转换处理
7. 销毁 bean
1. 处理名称,检查缓存
* 这一步会处理别名,将别名解析为实际名称
* 对 FactoryBean 也会特殊处理,如果以 & 开头表示要获取 FactoryBean 本身,否则表示要获取其产品
* 这里针对单例对象会检查一级、二级、三级缓存
* singletonFactories 三级缓存,存放单例工厂对象
* earlySingletonObjects 二级缓存,存放单例工厂的产品对象
* 如果发生循环依赖,产品是代理;无循环依赖,产品是原始对象
* singletonObjects 一级缓存,存放单例成品对象
2. 处理父子容器
* 如果当前容器根据名字找不到这个 bean,此时若父容器存在,则执行父容器的 getBean 流程
* 父子容器的 bean 名称可以重复
3. 处理 dependsOn
* 如果当前 bean 有通过 dependsOn 指定了非显式依赖的 bean,这一步会提前创建这些 dependsOn 的 bean
* 所谓非显式依赖,就是指两个 bean 之间不存在直接依赖关系,但需要控制它们的创建先后顺序
4. 选择 scope 策略
* 对于 singleton scope,首先到单例池去获取 bean,如果有则直接返回,没有再进入创建流程
* 对于 prototype scope,每次都会进入创建流程
* 对于自定义 scope,例如 request,首先到 request 域获取 bean,如果有则直接返回,没有再进入创建流程
5.1 创建 bean - 创建 bean 实例
5.2 创建 bean - 依赖注入
5.3 创建 bean - 初始化
5.4 创建 bean - 注册可销毁 bean
在这一步判断并登记可销毁 bean
* 判断依据
* 如果实现了 DisposableBean 或 AutoCloseable 接口,则为可销毁 bean
* 如果自定义了 destroyMethod,则为可销毁 bean
* 如果采用 @Bean 没有指定 destroyMethod,则采用自动推断方式获取销毁方法名(close,shutdown)
* 如果有 @PreDestroy 标注的方法
* 存储位置
* singleton scope 的可销毁 bean 会存储于 beanFactory 的成员当中
* 自定义 scope 的可销毁 bean 会存储于对应的域对象当中
* prototype scope 不会存储,需要自己找到此对象销毁
* 存储时都会封装为 DisposableBeanAdapter 类型对销毁方法的调用进行适配
6. 类型转换处理
如果 getBean 的 requiredType 参数与实际得到的对象类型不同,会尝试进行类型转换
7. 销毁 bean
* 销毁时机
* singleton bean 的销毁在 ApplicationContext.close 时,此时会找到所有 DisposableBean 的名字,逐一销毁
* 自定义 scope bean 的销毁在作用域对象生命周期结束时
* prototype bean 的销毁可以通过自己手动调用 AutowireCapableBeanFactory.destroyBean 方法执行销毁
* 同一 bean 中不同形式销毁方法的调用次序
* 优先后处理器销毁,即 @PreDestroy
* 其次 DisposableBean 接口销毁
* 最后 destroyMethod 销毁(包括自定义名称,推断名称,AutoCloseable 接口 多选一)