Spring的bean生命周期源码整理

本文对Spring初始化过程、bean的声明周期进行梳理,同时为了容易记忆,会将对Spring的常见使用和源码结合

 

spring的IOC容器初始化入口,位于org.springframework.context.support.AbstractApplicationContext#refresh方法

 几个重要的节点

(1)对beanDefination的自定义拦截和修改,由invokeBeanFactoryPostProcessors方法触发,执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,最常用的是org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry,这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解(参考ConfigurationClassPostProcessor —— Spring中最!最!最!重要的后置处理器!没有之一!!! - 掘金

 在postProcessBeanDefinitionRegistry方法内部有一个重要的回调,即ImportBeanDefinitionRegistrar的registerBeanDefinitions,实际应用经常通过实现该回调来将自定义的beandefinition注入容器,比如dubbo的DubboComponentScanRegistrar类

 该方法的importingClassMetadata参数可用来获取指定注解的信息,比如DubboComponentScanRegistrar就用它获取存在DubboComponentScan注解的包位置,以进行bean的初始化扫描

(2)BeanFactory内部,即invokeBeanFactoryPostProcessors方法调用,调用容器中定义的BeanFactoryPostProcessor的postProcessBeanFactory方法,根据官方注解,此时方法入参里的beanFactory中所有bean已经加载但未初始化

 可在方法内部获取bean的定义并记录,如下图

 另一个常见的用法是通过beanFactory.registerSingleton方法将自定义的bean(如rpc的server)注入容器,注意注入之前必须将bean完全初始化,调用registerSingleton后bean不会收到任何初始化和销毁的回调,AOP也会失效(参考spring动态注册bean会使AOP失效? - 腾讯云开发者社区-腾讯云

(3)注册BeanPostProcessor

 (4)接下来最重要的入口在BeanFactory的preInstantiateSingletons方法的调用,最重要的bean的初始化逻辑均在该方法内部,注意spring初始化过程的异常在这个方法抛出,过去在工作中这类异常无日志记载,往往需要使用arthas监听这个方法的执行才能获取异常

 该方法对factoryBean和普通bean的初始化进行了区分处理

 本文暂时只关注普通bean的初始化逻辑

(5)普通bean初始化逻辑的BeanFactory.getBean直接调用了AbstractBeanFactory#doGetBean方法,这是初始化一个bean的总入口。

 首先从熟悉的三级缓存中加载,如bean已在缓存则返回 ,三级缓存原理参考 spring5 源码深度解析-----IOC 之 循环依赖处理 - chen_hao - 博客园

 如bean未在缓存中,首先加载依赖的bean,同样调用BeanFactory.getBean方法,走上面同样的逻辑

 加载完依赖的bean,根据bean作用域(单例、protype等)的不同,走不同的初始化逻辑

 (6)本文暂只关注单例情况下的初始化方法,DefaultSingletonBeanRegistry#getSingleton

该方法主要做了两件事,一是标记bean在创建中,用于后续循环依赖的解决

 二是真正的bean创建过程,入口在AbstractAutowireCapableBeanFactory#createBean

 注意这里有一个重要的resolveBeforeInstantiation调用,这里允许BeanPostProcessor生成proxy类代替原始的bean,也就是AOP对象注入的地方

 接着开始最重要的bean创建过程

主要入口在AbstractAutowireCapableBeanFactory#doCreateBean,实现创建一个bean实例(没有特殊策略就通过默认构造函数来反射创建)

 接着判断当前bean是否还未创建完成就曝光,如是生成一个返回上步创建的bean对象的工厂对象放入第三级缓存中,供依赖它的bean使用

 接着前置工作都已完成,要真正进入bean的创建

  普通bean的创建分两大部分

 至此单例bean创建完成,回到单例bean的入口DefaultSingletonBeanRegistry#getSingleton,将创建完成的bean从二三级缓存删除,放入一级缓存

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值