当前位置: 首页 > news >正文

Spring源码学习(三):finishBeanFactoryInitialization

免责声明

本人还处于学习阶段,如果内容中存在错误请见谅,欢迎大家指出错误!!!

写在前面

​   beanFactory在经过一系列配置后可以开始真正的加载Bean,从这篇开始主要是讲述Bean的实例化过程。

1.finishBeanFactoryInitialization干了什么

​  下面是finishBeanFactoryInitialization方法的实现,前面进行了一些配置,核心部分其实在preInstantiateSingletons里面。需要注意的是调用了freezeConfiguration方法,该方法会冻结Bean定义,但是之前讲过BeanFactoryPostProcessor可以修改bBean定义,因此BeanFactoryPostProcessor的方法回调会在freezeConfiguration之前。

在这里插入图片描述

2. preInstantiateSingletons干了什么

​   preInstantiateSingletons里面主要处理了FactoryBeanSmartFactory和普通的Bean,这三者实例化的时机略有区别,因此做了对应的处理。

​   此外,在初始化完成所有Bean之后,该方法还会对实现了SmartInitializingSingleton接口的Bean进行方法回调,可以看到这个方法回调的时机算比较晚的了,在BeanPostProcessor之后。

​   关于实例化Bean的逻辑还要进去getBean方法。

在这里插入图片描述

在这里插入图片描述

3. getBean方法做了什么

​   首先会调用父类AbstractBeanFactorydoGetBean方法。该方法内部其实也并未涉及Bean的初始化,主要是针对父容器、原型Bean、单例Bean等做了相应的处理。

在这里插入图片描述

在这里插入图片描述
  getObjectForBeanInstance方法其实是处理FactoryBean这种特殊情况:

在这里插入图片描述
  我们继续看doGetBean的逻辑:
在这里插入图片描述

在这里插入图片描述

​   有关初始化Bean的核心逻辑还需要继续深入到createBean方法中。

​   Spring有个小特点,往往会将主要逻辑写在do+方法名中,因此还得去doCreateBean中。

在这里插入图片描述

4.createBean做了什么

在这里插入图片描述

4.1 createBean

  按照Spring命名的特点,真正的逻辑应该在doCreateBean中,我们先看看createBean
在这里插入图片描述

4.1.1 resolveBeforeInstantiation干了什么

在这里插入图片描述

在这里插入图片描述
  如果我们走了component-scan逻辑,这里确实会有InstantiationAwareBeanPostProcessor类型的后处理器,但是这三个后处理器内部的applyBeanPostProcessorsBeforeInstantiation方法都返回了一个空值,因此,如果采用默认的后处理器,其实resolveBeforeInstantiation方法没有干任何事情。

4.2 doCreateBean

  真正实例化一个对象通常分为三步骤:实例化-》属性填充-》初始化。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2.1 createBeanInstance

  我们先来看看第一个步骤,如何实例化一个Bean,它的一个核心思想是获取构造器通过反射完成实例化:
在这里插入图片描述

在这里插入图片描述

4.2.1.1 determineConstructorsFromBeanPostProcessors

  determineConstructorsFromBeanPostProcessors方法主要通过回调后处理器的determineCandidateConstructors方法来获取候选构造器:
在这里插入图片描述
  当前beanFactory中有确实有两个后处理器是SmartInstantiationAwareBeanPostProcessor类型的:ImportAwareBeanPostProcessorAutowiredAnnotationBeanPostProcessor

​   其中ImportAwareBeanPostProcessor里面的determineCandidateConstructors方法是空实现,获取候选构造器的主要逻辑在AutowiredAnnotationBeanPostProcessordetermineCandidateConstructors方法中。

​   需要注意的是:

在这里插入图片描述

​   让我们继续进入到AutowiredAnnotationBeanPostProcessor中的determineCandidateConstructors方法去看看,是如何获得候选构造器的,由于代码太长,分块讲解一下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
  根据2.4中的逻辑,可以得到以下结论:

1.如果有两个及以上构造器的@Autowired注解的required属性为true,抛出异常。
2.当有一个构造器的@Autowired注解的required属性为true,不允许有其他@Autowired注解。
3.当有一个构造器的@Autowired注解的required属性为true,不会考虑无参构造。
4.当有多个@Autowired注解,并且required属性都为false,这些构造器和无参构造器都会加入到候选构造器数组中。![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e0853890a2884ada9e0bcb8eae0f4bbd.png#pic_center)
4.2.1.2 autowireConstructor

​   前面已经通过determineConstructorsFromBeanPostProcessors获得了候选构造器ctors,接下来就就要对候选构造器中的参数进行解析注入,并实例化对象。

​   autowireConstructor底层是通过创建ConstructorResolver对象,然后调用ConstructorResolverautowireConstructor方法,还是采取分块解析的方式:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2.1.3 简单看看instantiate干了什么

​   获得当前工厂的策略器,默认是CglibSubclassingInstantiationStrategy,该策略器调用父类SimpleInstantiationStrategyinstantiate方法完成Bean的实例化:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2.2 applyMergedBeanDefinitionPostProcessors

在这里插入图片描述

​   可以看到当前beanFactory中的后处理器中,有三个都是MergedBeanDefinitionPostProcessor类型的,分别去回调里面的postProcessMergedBeanDefinition方法。

在这里插入图片描述
  简单说说这三个MergedBeanDefinitionPostProcessor类型的后处理器里面的postProcessMergedBeanDefinition方法:

​   AutowiredAnnotationBeanPostProcessor后处理器处理@Autowired、@Value、@Inject注解的字段和成员方法,将这些信息保存下来。

在这里插入图片描述

​   让我们简单看看buildAutowiringMetadata方法:
在这里插入图片描述
  ApplicationListenerDetector后处理器主要来缓存单例的ApplicationListener的beanName:

在这里插入图片描述
  我们之前也提到过,ApplicationListenerDetector也重写了postProcessAfterInitialization方法,该方法会在bean初始化结束后执行:

在这里插入图片描述
  CommonAnnotationBeanPostProcessor后处理器处理@WebServiceRef、@EJB、@Resource注解,其postProcessMergedBeanDefinition方法的逻辑和AutowiredAnnotationBeanPostProcessor一致,这里就不贴源代码了。

4.2.2 addSingletonFactory

在这里插入图片描述

​   可以看到缓存到第三级缓存中的是一个lambda表达式,当我们从singletonFactories中获取该bean时,返回的其实是getEarlyBeanReference的返回值,getEarlyBeanReference的实现如下:

在这里插入图片描述

​   SmartInstantiationAwareBeanPostProcessor类型的后处理器其实在createBeanInstance时也用过,当时是通过回调后处理器的determineConstructorsFromBeanPostProcessors方法来获得候选构造器,这里是调用getEarlyBeanReference。当前beanFactory中有六个后处理器其中有俩属于SmartInstantiationAwareBeanPostProcessor

在这里插入图片描述

​   有意思的是,它的实现类也都是默认返回传递的参数bean实例,也就是说Spring在这个扩展点方法中没有任何额外操作

4.2.3 populateBean

在这里插入图片描述

在这里插入图片描述

4.2.4 initializeBean

​   在完成实例化和属性填充后开始初始化操作,包括回调各种方法,并执行自己的init方法(如果有的话):

在这里插入图片描述


http://www.mrgr.cn/news/64073.html

相关文章:

  • 【前端基础】CSS进阶
  • 群控系统服务端开发模式-应用开发-系统配置开发
  • 鸿蒙生态认识
  • AAA 数据库事务隔离级别及死锁
  • Mybatis-plus入门教程
  • ICPC区域赛成都站【赛后回顾+总结】
  • 亚马逊降佣刺激印度市场,中小卖家利好消息,测评助力扬帆起航
  • YOLOv11改进策略【注意力机制篇】| CVPRW-2024 分层互补注意力混合层 H-RAMi 针对低质量图像的特征提取模块
  • 【算法+C#】重写HashCode,去重相同坐标的二维点
  • 全面解析 ESPnet:Aishell 项目深入指南
  • 2025院士增选高校候选人名单公布,医工交叉领域有这些专家需要重点关注!|24-11-02
  • 2-8软件包管理
  • 7、LVM逻辑卷详解
  • tmux查看的日志范围有限
  • Django 5企业级Web应用开发实战-日志
  • DNS服务器
  • openGauss数据库-头歌实验1-3 创建和管理模式
  • C++ 实现俄罗斯方块游戏
  • DPDK event 驱动开发
  • 【数据库】用关系代数的基本运算来表示其他运算
  • 一台手机可以登录运营多少个TikTok账号?
  • 少样本无标签室内定位论文精华-20241102
  • clion远程配置docker ros2
  • 【Java语言】继承和多态(一)
  • 小夜灯语音识别芯片,灯具声控方案,NRK3301
  • Linux初阶——线程(Part3):POSIX 信号量 CP 模型变体