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
    评论
Spring框架提供了对Bean生命周期管理。在Spring码中,Bean生命周期由两个关键接口定义:BeanFactory和BeanPostProcessor。 BeanFactory是Spring的核心接口之一,它负责管理所有的Bean,并负责实例化、配置和管理它们的整个生命周期BeanFactory接口定义了许多方法,如getBean()和registerBeanDefinition(),用于获取和注册BeanBeanPostProcessor是另一个重要的接口,它定义了在Bean初始化的不同阶段可以插入自定义逻辑的扩展点。通过实现BeanPostProcessor接口,开发人员可以在Bean的实例化、初始化和销毁等阶段插入自己的逻辑。BeanPostProcessor接口中定义了两个方法:postProcessBeforeInitialization()和postProcessAfterInitialization()。 在Spring码中,Bean生命周期主要涉及以下几个重要的类和方法: 1. DefaultListableBeanFactory类:此类实现了BeanFactory接口,是Spring容器的核心实现类之一。它负责读取Bean的定义信息,并根据这些定义信息创建和管理Bean。 2. AbstractAutowireCapableBeanFactory类:此类是DefaultListableBeanFactory的子类,它提供了Bean的自动装配功能。它包含了Bean的实例化、属性注入、初始化和销毁等关键步骤。 3. AnnotationConfigApplicationContext类:此类是通过注解配置来创建Spring容器的一种方式。它根据指定的配置类,扫描注解并完成Bean的初始化和管理。 4. BeanDefinition类:此类定义了Bean的配置信息,包括Bean的类名、属性值和依赖关系等。在Bean生命周期中,BeanDefinition起到了重要的作用。 以上只是Spring Bean生命周期码的一部分,如果你对Spring Bean生命周期码感兴趣,建议你阅读Spring码以获得更详细的了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值