|
|
# bean生命周期12个环节
|
|
|
1. 阶段1:Bean元信息配置阶段
|
|
|
2. 阶段2:Bean元信息解析阶段
|
|
|
3. 阶段3:将Bean注册到容器中
|
|
|
4. 阶段4:BeanDefinition合并阶段
|
|
|
5. 阶段5:Bean Class加载阶段
|
|
|
6. 阶段6:Bean实例化阶段(2个小阶段)
|
|
|
+ Bean实例化前阶段
|
|
|
+ Bean实例化阶段
|
|
|
7. 阶段7:合并后的BeanDefinition处理
|
|
|
8. 阶段8:属性复制阶段(3个小阶段)
|
|
|
+ Bean实例化后阶段
|
|
|
+ Bean属性赋值前阶段
|
|
|
+ Bean属性赋值阶段
|
|
|
9. 阶段9:Bean初始化阶段(5个小阶段)
|
|
|
+ Bean Aware接口回调阶段
|
|
|
+ Bean初始化前阶段
|
|
|
+ Bean初始化阶段
|
|
|
+ Bean初始化后阶段
|
|
|
10. 阶段10:所有单例bean初始化完成后阶段
|
|
|
11. 阶段11:Bean使用阶段
|
|
|
12. 阶段12:Bean销毁前阶段
|
|
|
13. 阶段13:Bean销毁阶段
|
|
|
|
|
|
# 阶段1:Bean元信息配置阶段
|
|
|
这个阶段是Bean信息的定义阶段
|
|
|
## Bean信息定义4中方式
|
|
|
+ API方式
|
|
|
+ Xml文件
|
|
|
+ properties文件
|
|
|
+ 注解
|
|
|
|
|
|
## API方式
|
|
|
其他三种方式最后都会转成API方式定义bean配置信息
|
|
|
Spring容器启动过程中,会将Bean解析成Spring内部的BeanDefinition对象,bean工厂会根据定义信息对bean进行实例化、初始化
|
|
|
![[Snipaste_2023-02-16_14-33-18.png]]
|
|
|
|
|
|
### 例
|
|
|
![[Snipaste_2023-02-16_14-37-20.png]]
|
|
|
![[Snipaste_2023-02-16_14-37-54.png]]
|
|
|
![[Snipaste_2023-02-16_14-38-23.png]]
|
|
|
|
|
|
|
|
|
# 阶段2:Bean元信息阶段解析
|
|
|
解析就是将各种方式定义的bean配置信息解析为BeanDefinition对象
|
|
|
## 元信息解析的3种方式
|
|
|
1. xml文件定义Bean的解析
|
|
|
2. properties文件定义bean的解析
|
|
|
3. 注解方式定义bean的解析
|
|
|
|
|
|
### XML方式解析:XmlBeanDefinitionReader
|
|
|
将xml中定义的bean解析为BeanDefinition对象
|
|
|
![[Snipaste_2023-02-16_14-38-23 1.png]]
|
|
|
|
|
|
![[Snipaste_2023-02-16_14-45-54.png]]
|
|
|
|
|
|
### 注解方式:AnnotatedBeanDefinitionReader
|
|
|
![[Snipaste_2023-02-16_14-49-03.png]]
|
|
|
|
|
|
![[Snipaste_2023-02-16_14-50-33.png]]
|
|
|
|
|
|
# 阶段3:Spring Bean注册阶段
|
|
|
bean注册阶段需要用:BeanDefinitionRegistry
|
|
|
|
|
|
## Bean注册接口:BeanDefinitionRegistry
|
|
|
Spring中BeanDefinitionRegistry接口有一个唯一的实现类:
|
|
|
**DefaultListableBeanFactory**
|
|
|
有很多类也实现了 BeanDefinitionRegistry 接口,比如我们经常用到AnnotationConfigApplicationContext ,但实际上其内部是转发给了
|
|
|
DefaultListableBeanFactory 进行处理的,所以真正实现这个接口的类是DefaultListableBeanFactory
|
|
|
|
|
|
### 例
|
|
|
![[Snipaste_2023-02-16_15-02-43.png]]
|
|
|
|
|
|
# 阶段4:BeanDefinition合并阶段
|
|
|
|
|
|
## 合并阶段
|
|
|
定义bean的时候有父子bean关系,此时子BeanDefinition中的信息是不完整,比如设置属性的适合配置在父BeanDefinition中,此时子BeanDefinition中是没有这些信息的,需要将子bean的BeanDefinition和父bean的BeanDefinition进行合并,得到一个RootBeanDefinition。其包含bean定义的所有信息,包含了从父bean中继承过来的所有信息,后续的创建工作需要依靠RootBeanDefinition进行
|
|
|
|
|
|
## 例
|
|
|
![[Snipaste_2023-02-16_15-11-35.png]]
|
|
|
![[Snipaste_2023-02-16_15-12-03.png]]
|
|
|
|
|
|
从输出的结果中可以看到,合并之前,BeanDefinition是不完整的,比lesson2和lesson3中的class是null,属性信息也不完整,但是合并之后这些信息都完整了。
|
|
|
合并之前是 GenericBeanDefinition 类型的,合并之后得到的是 RootBeanDefinition 类型的。
|
|
|
获取lesson3合并的BeanDefinition时,内部会递归进行合并,先将lesson1和lesson2合并,然后将
|
|
|
lesson2再和lesson3合并,最后得到合并之后的BeanDefinition。后面的阶段将使用合并产生的RootBeanDefinition。
|
|
|
|
|
|
# 阶段5:Bean Class加载阶段
|
|
|
这个阶段就是将bean的class名称转换为class类型的对象
|
|
|
BeanDefinition中有个Object类型的字段:beanClass,用来表示bean的class对象。这个字段有2种类型,一种是bean对应的Class类型的对象,另一种是bean对应的Class的完整类名,第一种情况不需要解析,第二种情况:即这个字段是bean的类名的时候,就需要通过类加载器将其转换为一个Class对象(此时会对阶段4种合并产生的RootBeanDefinition种的beanClass进行解析,将bean的类名转换为Class对象,然后赋值给beanClass字段)。
|
|
|
|
|
|
# 阶段6:Bean实例化阶段
|
|
|
## 1.Bean实例化前操作
|
|
|
先来看一下 DefaultListableBeanFactory,这个类中有个非常非常重要的字段:
|
|
|
实际上这个字段是在AbstractBeanFactory中
|
|
|
![[Snipaste_2023-02-16_15-28-45.png]]
|
|
|
BeanPostProcessor是一个接口,还有很多子接口,这些接口中提供了很多方法,spring在bean生命
|
|
|
周期的不同阶段,会调用上面这个列表中的BeanPostProcessor中的一些方法,来对生命周期进行扩
|
|
|
展,bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的,很多以BeanPostProcessor结尾的,都实现了BeanPostProcessor接口,有些是直接实现的,有些是实现了它的子接口。
|
|
|
|
|
|
![[Snipaste_2023-02-16_15-31-05.png]]
|
|
|
|
|
|
## 2.Bean实例化操作
|
|
|
**通过反射调用bean的构造器来创建bean的实例**,具体用哪个构造器,spring允许开发者自己进行判断。
|
|
|
![[Snipaste_2023-02-16_15-33-47.png]]
|
|
|
|
|
|
# 阶段7:合并后的BeanDefinition处理
|
|
|
|
|
|
# 阶段8:Bean属性设置阶段
|
|
|
+ 实例化后阶段
|
|
|
+ Bean属性赋值前处理
|
|
|
+ Bean属性赋值
|
|
|
## 1.实例化后阶段
|
|
|
![[Snipaste_2023-02-16_15-44-55.png]]
|
|
|
## 2.Bean属性赋值前处理
|
|
|
![[Snipaste_2023-02-16_15-45-48.png]]
|
|
|
AutowiredAnnotationBeanPostProcessor在这个方法中对@Autowired、@Value标注的字段、方
|
|
|
法注入值。
|
|
|
CommonAnnotationBeanPostProcessor在这个方法中对@Resource标注的字段和方法注入值。
|
|
|
|
|
|
## 3.Bean属性赋值
|
|
|
循环处理 PropertyValues 中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。
|
|
|
PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中
|
|
|
add方法设置的值。
|
|
|
|
|
|
|
|
|
# 阶段9:Bean初始化阶段
|
|
|
+ Bean Aware接口回调
|
|
|
+ Bean初始化前操作
|
|
|
+ Bean初始化操作
|
|
|
+ Bean初始化后操作
|
|
|
+ Bean初始化完成操作
|
|
|
|
|
|
## Bean Aware接口回调
|
|
|
![[Snipaste_2023-02-16_15-45-48 1.png]]
|
|
|
## Bean初始化前操作
|
|
|
![[Snipaste_2023-02-16_15-45-48 2.png]]
|
|
|
![[Snipaste_2023-02-16_15-45-48 3.png]]
|
|
|
## Bean初始化操作
|
|
|
1. 调用InitializingBean接口的afterPropertiesSet方法
|
|
|
2. 调用定义bean时候指定的初始化方法
|
|
|
![[Snipaste_2023-02-16_15-45-48 4.png]]
|
|
|
### 指定Bean的初始化方法
|
|
|
![[Snipaste_2023-02-16_16-02-36.png]]
|
|
|
## Bean初始化后操作
|
|
|
![[Snipaste_2023-02-16_16-04-16.png]]
|
|
|
## Bean初始化完成操作
|
|
|
|
|
|
# 阶段10:所有单例bean初始化完成后阶段
|
|
|
![[Snipaste_2023-02-16_16-04-16 1.png]]
|
|
|
|
|
|
|
|
|
# 阶段11:Bean使用阶段
|
|
|
|
|
|
# 阶段12:Bean销毁阶段
|
|
|
## 触发bean销毁的3种方式
|
|
|
1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
|
|
|
2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
|
|
|
3. 调用bean自定义的销毁方法
|
|
|
|
|
|
![[Snipaste_2023-02-16_16-04-16 2.png]]
|
|
|
|
|
|
![[Snipaste_2023-02-16_16-04-16 3.png]] |