You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

bean生命周期12个环节

  1. 阶段1Bean元信息配置阶段
  2. 阶段2Bean元信息解析阶段
  3. 阶段3将Bean注册到容器中
  4. 阶段4BeanDefinition合并阶段
  5. 阶段5Bean Class加载阶段
  6. 阶段6Bean实例化阶段2个小阶段
    • Bean实例化前阶段
    • Bean实例化阶段
  7. 阶段7合并后的BeanDefinition处理
  8. 阶段8属性复制阶段3个小阶段
    • Bean实例化后阶段
    • Bean属性赋值前阶段
    • Bean属性赋值阶段
  9. 阶段9Bean初始化阶段5个小阶段
    • Bean Aware接口回调阶段
    • Bean初始化前阶段
    • Bean初始化阶段
    • Bean初始化后阶段
  10. 阶段10所有单例bean初始化完成后阶段
  11. 阶段11Bean使用阶段
  12. 阶段12Bean销毁前阶段
  13. 阶段13Bean销毁阶段

阶段1Bean元信息配置阶段

这个阶段是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

阶段2Bean元信息阶段解析

解析就是将各种方式定义的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

阶段3Spring Bean注册阶段

bean注册阶段需要用BeanDefinitionRegistry

Bean注册接口BeanDefinitionRegistry

Spring中BeanDefinitionRegistry接口有一个唯一的实现类 DefaultListableBeanFactory 有很多类也实现了 BeanDefinitionRegistry 接口比如我们经常用到AnnotationConfigApplicationContext ,但实际上其内部是转发给了 DefaultListableBeanFactory 进行处理的所以真正实现这个接口的类是DefaultListableBeanFactory

!Snipaste_2023-02-16_15-02-43.png

阶段4BeanDefinition合并阶段

合并阶段

定义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。

阶段5Bean Class加载阶段

这个阶段就是将bean的class名称转换为class类型的对象 BeanDefinition中有个Object类型的字段beanClass用来表示bean的class对象。这个字段有2种类型一种是bean对应的Class类型的对象另一种是bean对应的Class的完整类名第一种情况不需要解析第二种情况即这个字段是bean的类名的时候就需要通过类加载器将其转换为一个Class对象此时会对阶段4种合并产生的RootBeanDefinition种的beanClass进行解析将bean的类名转换为Class对象然后赋值给beanClass字段

阶段6Bean实例化阶段

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处理

阶段8Bean属性设置阶段

  • 实例化后阶段
  • 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方法设置的值。

阶段9Bean初始化阶段

  • 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

阶段11Bean使用阶段

阶段12Bean销毁阶段

触发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