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

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.kler.cn/a/378003.html

相关文章:

  • Apifox 12月更新|接口的测试覆盖情况、测试场景支持修改记录、迭代分支能力升级、自定义项目角色权限、接口可评论
  • Java基础知识(四) -- 面向对象(下)
  • win版ffmpeg的安装和操作
  • C++第五六单元测试
  • 深度学习中的并行策略概述:2 Data Parallelism
  • Nginx的性能分析与调优简介
  • 线程安全的单例模式(Singleton)。
  • 轮廓图【HTML+CSS+JavaScript】
  • Java日志脱敏(二)——fastjson Filter + 注解 + 工具类实现
  • 统信UOS开发环境支持php
  • 使用Vite构建现代化前端应用
  • 使用AIM对SAP PO核心指标的自动化巡检监控
  • SQL,力扣题目1285,找到连续区间的开始和结束数字【窗口函数】
  • VsCode前端常用快捷键
  • 冷钱包与热钱包的差异 | 加密货币存储的安全方案
  • 03.DDD六边形架构
  • apache pdfbox 设置PDF表单域,Java生成PDF模板简单案例。
  • 【ARCGIS实验】地形特征线的提取
  • Spring Boot框架下校园社团信息管理的创新实践
  • 图像识别中的高斯滤波和椒盐滤波的适用场景与不同实现
  • SpringBoot 集成 Mybatis-Plus,LambdaQueryWrapper 使用方法
  • Git 本地操作(2)
  • Razor C# 逻辑
  • -XSS-
  • Qt的程序如何打包详细教学
  • React常用前端框架合集