Spring bean 的生命周期(总结)

时间:2022-10-18 21:58:36

Spring bean 的生命周期


起点:protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)

  • 阶段1:处理名称,检查缓存;
  • 阶段2:检查父工厂;
  • 阶段3:检查 DependsOn;
  • 阶段4:按 Scope 创建 bean;
    • 创建 singleton;
    • 创建 prototype;
    • 创建其它 scope 。
  • 阶段5:创建 bean;
    • 创建 bean 实例;
    • 依赖注入;
    • 初始化;
    • 登记可销毁 bean 。
  • 阶段6:类型转换;
  • 阶段7:销毁 bean 。


1、阶段1 —— 处理名称,检查缓存

要点:

  • 别名处理

    ​ 别名解析成实际名称。

  • FactoryBean 的名字规范

    ​ 若要 FactoryBean 本身,需要使用 & 名称获取。

  • 三级缓存(解决循环依赖问题)

    • singletonObjects:一级缓存,放单例成品对象;
    • earlySingletonObjects:二级缓存,放单例工厂的产品,可称为提前单例对象;
    • singletonFactories:三级缓存,放单例工厂。


2、阶段2 —— 检查父工厂

要点:

  • 有父工厂时的查找规则

    ​ 父子工厂的 bean 名称可以重复,当出现重复时,优先找子工厂的 bean,找到了直接返回,找不到继续到父工厂找。



3、阶段3 —— dependsOn

要点:

  • @dependsOn

    ​ @dependsOn 用于非显式依赖的 bean 的创建顺序控制。



4、阶段4 —— 按 Scope 创建 bean

要点:

  • 三种 scope(GenericApplicationContext 类)
    • 单例(singleton) bean:从 refresh() 被创建,到 close() 被销毁;
    • 多例(prototype) bean:从首次 getBean() 被创建,到调用 BeanFactory 的 destroyBean() 被销毁;
    • request bean:从首次 getBean() 被创建,到 request 结束前被销毁。


5、阶段5 —— 创建 bean

要点:

  • 创建 bean 实例

    • AutowiredAnnotationBeanPostProcessor 选择构造;
      • 优先 @Autowired;
      • 仅有唯一的带参构造器。
    • 默认构造。
  • 依赖注入

    • AutowiredAnnotationBeanPostProcessor 注解匹配;
      • 识别 @Autowired、@Value 标注的成员,封装为 InjectionMetadata 进行依赖注入。
    • CommonAnnotationBeanPostProcessor 注解匹配;
      • 识别 @Resource 标注的成员,封装为 InjectionMetadata 进行依赖注入。
    • AUTOWIRE_BY_NAME 根据名字匹配;
      • (RootBeanDefinition)setAutowiredMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME) 设置。
    • AUTOWIRE_BY_TYPE 根据类型匹配;
      • (RootBeanDefinition)setAutowiredMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE) 设置。
    • applyPropertyValues(即 xml 中的 <property name ref|value/> 或 bean.getPropertyValues().add(propertyName, runtimeBeanReference) )精确指定。
  • 依赖注入优先级(由低到高)

    • @Autowired;
    • AUTOWIRE_BY_NAME / AUTOWIRE_BY_TYPE;
    • applyPropertyValues 。
  • 初始化

    • 内置 Aware 接口的配置;
      • BeanNameAware 接口、BeanFactoryAware 接口等。
    • 扩展 Aware 接口的配置;
      • ApplicationContextAwareProcessor 解析;
      • postProcessBeforeInitialization() 执行。
    • @POSTConstruct;
      • CommonAnnotationBeanPostProcessor 解析;
      • postProcessBeforeInitialization() 执行。
    • InitializingBean 接口;
    • initMethod()(即 <bean init-method> 或 @Bean(initMethod));
    • 创建 aop 代理。
      • AnnotationAwareAspectJAutoProxyCreator 创建;
      • postProcessAfterInitialization() 执行。
  • 初始化顺序

    • Bean 构造器;
    • BeanFactoryAware;
    • @PostConstruct;
    • InitializingBean 接口;
    • initMethod()。
  • 注册可销毁 bean

    • 判断依据:
      • 实现 DisposableBean 或 AutoCloseable 接口;
      • 自定义了 destroyMethod();
      • 通过自动推断方式获取销毁方法名(如 close(),shutdown());
      • @PreDestroy 标注的方法。
    • 存储位置:
      • beanFactory 成员中(singleton scope 的 bean);
      • 对应的域对象中(自定义 scope 的 bean);
      • 特例:prototype scope 的 bean 不会存储,需要手动销毁;
      • 注:存储时都会封装为 DisposableBeanAdapter 类型对销毁方法的调用进行适配(适配器模式)。


6、阶段6 —— 类型转换

要点:

  • 类型转换

    • 如果 getBean 的 requiredType 参数与实际得到的对象类型不同,会尝试进行类型转换。


7、阶段7 —— 销毁 bean

要点:

  • singleton bean 的销毁时机
    • 在调用 ApplicationContext.close() 时,会找到所有 DisposableBean 的名字,逐一销毁。
  • 自定义 scope bean 的销毁时机
    • 作用域对象生命周期结束时,调用相对应的销毁方法;
  • prototype bean 的销毁时机
    • 手动调用 AutowireCapableBeanFactoryAware.destoryBean() 执行销毁;
  • 同一 bean 中不同形式销毁方法的调用次序(由高到低)
    • 优先后处理器销毁,即 @PreDestroy;
    • DisposableBean 接口销毁;
    • destroyMethod() 销毁(如 自定义名称、推断名称、AutoCloseable 接口)。


来源:https://www.bilibili.com/video/BV15b4y117RJ?p=151&spm_id_from=pageDriver&vd_source=8b6dfb9416c7aad22744de7bcdae9a95