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