Spring Bean 生命周期

背景

spring 使用了 IOC 模型,让对象存储在了容器中,每当使用时我们可以通过依赖注入的方式获取 bean 对象。

而因为 bean 对象是交由容器来管理的,故就有了生命周期的概念。

先讲下 spring 的容器有哪些。

spring 的容器

spring 有 BeanFacotry(bean 工厂) 和 ApplicationContext (应用上下文)

区别:

  • beanfactory 只提供了基础的 bean 存储功能和依赖注入功能,版本控制功能。
  • applicationcontext 继承了 beanfactory 的特性,还提供了大量扩展,能根据配置文件 xml 来实现国际化,事件传播,资源加载等,也支持 J2EE 的一些特性。
  • BeanFactory 的 bean 是延时加载,ApplicationContext 是非延时加载。

bean 生命周期

实例化 spring 容器

beandifinition bean 定义:通过@compomentscan 来扫描 bean 对象

解析扫描的对象,从而获取 bean 类的信息,例如抽象类,懒加载等。

创建 beanDefinition 图纸,将 bean 的信写吸入 map 中

BeanFactoryPostProcessor 类可以干预原先的类定义,即干预图纸。

遍历图纸,根据图纸造对象 preInstantiateSingletons() 遍历所有的 bean定义,判断这个类不是抽象的,不是单例的,不是懒加载的,再去创建。

实例化对象 反射(还没注入到容器)

缓存注解信息,解析合并后的 beandifinition 对象

提前暴露一个对象工程 - 循环依赖

判断实例化的对象里面的属性是否要注入依赖 - 默认需要注入

回调部分 aware 接口,因为 spring 内置了很多 aware,调用的时机是不同,这里只调用部分。

执行部分 aware,调用生命周期初始化回调方法

执行生命周期初始化回调的接口行驶的方法

  • 有容器生命周期和bean 生命周期,这部分是bean 生命周期。
  • 有注解版,配置文件版,接口版
  • @PostConstruct 注解的方法是 bean 初始化方法
  • @PostDestory 注解的方法是 bean 销毁的方法。
  • 多个版本可以同时存在。先执行接口版,再执行注解版,最后执行配置文件版。

完成代理 - aop,事件分发,发布监听

put 单例池容器

销毁整个容器对象

  1. 实例化 spring 容器,创建 beanFactory
  2. 扫描符合 springbean 规则(@bean)的 class -- 集合
  3. 遍历集合当中的类,封装成一个 beanDefinitionMap 对象
  4. 遍历 beanDefinitionMap 对象
  5. 解析 -- validate
  6. 通过 beanDefinitionMap 获取 类的信息
  7. 得到构造方法 -- 通过算法推断出合理的构造方法
  8. 通过这个合理的构造方法反射实例化一个对象。
  9. 提前暴露工厂 -- 循环依赖
  10. 注入属性 -- 判断是否需要完成属性填充:自动注入
  11. 执行部分的 aware 接口(beannameAware,BeanClassLoaderAware,BeanFactoryAware)
  12. 执行部分 aware 接口和 lifecycle callback 注解版
  13. 若 bean 关联了 BeanPostProcessor 接口,将会调用 postProcessBefforeInitialization 方法,主要对 bean 内容进行更改。
  14. 执行初始化方法 init-method。
  15. 若 bean 关联了 BeanPostProcessor 接口,这时还会调用 postProcessAfterInitialization 方法。
  16. aop 动态代理,事件分发,发布监听等。
  17. put singletonobjects 放入单例池
  18. destroy() 销毁方法

代码:

  1. invokeBeanFactoryPostProcessors(Factory)
    • 扫描,拆改那就 BeanDefinition
    • 执行 beanFactoryPostProcessors
updatedupdated2022-06-232022-06-23