Spring IOC容器初始化 -- doCreateBean()方法详解

「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

1.前言

这个方法的主要作用就是创建bean,不过前提是bean的预创建处理,需要已经完成。 bean的预创建处理,我在前面 Spring IOC容器初始化 -- createBean()方法详解 中已经分析过了,大家感兴趣的可以自己看看。

2.doCreateBean() 源码

ps: 因为这个方法比较长,这里我就分段讲吧。

1. 在讲这段之前,建议大家先看看 BeanWrapper详解

图片.png

图片.png

  • 这块代码主要作用就是,给这个bean 创建出对应的 BeanWrapper 对象。
    1. 如果它是单例的,说明这个对象只会被创建一次,所以我们从 factoryBeanInstanceCache (在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getTypeForFactoryBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, boolean),判断当它是单列的时候调用: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck , 这里进行的 put 操作) 中取出时,直接可以移除。
    2. 如果instanceWrapper 为null,则调用 createBeanInstance(beanName, mbd, args)(后面细讲),创建出 BeanWrapper 对象。
    3. 拿到该 BeanWrapper,封装的 bean 实例,和bean的 class 对象。当 beanType 不是 NullBean(空的bean实现)类型时,修改它beanDefinition 中的 resolvedTargetType

2. 这部分是紧接,第一部分之后的 源码如下:

图片.png

  • postProcessed 标记字段,表示是否执行了 MergedBeanDefinitionPostProcessor 中的 postProcessMergedBeanDefinition 方法

  • applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

    图片.png

  • 通过源码我们可以看到,它会获取 所有的的 BeanPostProcessor ,如果该 beanPostProcessor 是 MergedBeanDefinitionPostProcessor 类型的 则会执行它的 postProcessMergedBeanDefinition 方法,执行完后,把 postProcessed 置为true。

  • MergedBeanDefinitionPostProcessor:属性合并的后置的后置处理器,通常在 postProcessMergedBeanDefinition 中,进行注解扫描,属性注入。

3. 急切地缓存单例能够解决循环引用,即使在像Beanfactoryaware这样的生命周期接口触发时。

图片.png

  • 当 创建的bean是单例的 && 允许循环引用 && 当前bean正在创建中,返回true
  • 当返回结果是 true 时,进入if.

3.1 getEarlyBeanReference(beanName, mbd, bean)

图片.png

  • 判断当前的bean 定义是否是合成的 && 返回是否已注册任何InstantiationAwareBeanPostProcessors
  • earlySingletonExposure : 是否需要提前曝光。
  • 取出所有的 BeanPostProcessors 进行遍历,当它是 SmartInstantiationAwareBeanPostProcessor 类型时,执行它的 getEarlyBeanReference 方法 。获取bean的引用对象,并返回。

3.2 default Object getEarlyBeanReference(Object bean, String beanName)(org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference)

主要作用:获取用于早期访问指定bean的引用,通常用于解析循环引用。 图片.png

  • 生成该 bean 的key

图片.png

  • 如果该beanname 为null 则直接返回 该beanClass
  • 当该 beanName 不为null 判断如果 beanClass 是 FactoryBean 的子类,则在 beanName前面拼上 “&” 前缀,返回beanName。

图片.png

  • 把生成的key 和 bean 放到这个map 中去 。

  • earlyProxyReferences : 记录提前曝光的 bean.

  • 返回生成的代理对象,或它本身。ps:wrapIfNecessary 这个方法后续细讲

3.3 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)

主要作用: 如果需要的话,添加给定的单例工厂来构建指定的单例。,用于单例的紧急注册,例如能够解析循环引用。 图片.png

  • 首先判断 一级缓存中有没有,若一级缓存没有
  • 则把它放到三级缓存中去,把它从二级缓存中移除
  • 把它添加到已注册单例的set集合中去,按注册顺序包含bean名称

4. 这部分的主要作用就是初始化 bean 实例

图片.png ps: 这里面的 populateBean 和 initialzeBean 都是比较重要的,后面的文章中我会详细讲讲

  • populateBean: Spring容器会对bean进行填充,将各个属性值注入,注入相关的依赖Bean
  • initialzeBean: 在这个方法主要是完成bean 的初始化过程。调用 后置处理器 BeanPostProcessor 里面的postProcessBeforeInitialization方法, 调用 initialzingBean,调用实现的 afterPropertiesSet(),调用 init-mothod,调用相应的init方法,调用 后置处理器 BeanPostProcessor 里面的调用实现的postProcessAfterInitialization方法

5. 处理需要提前曝光的对象

图片.png

  • earlySingletonExposure:是否提前曝光,如果需要提前曝光则进入。
  • 调用 getSingleton 获取该beanName 下注册的单实例对象。(ps:getSingleton详解:4.3)。这里只有当检测到会有循环依赖的时候,earlySingletonReference 才会不为null
  • exposedObject == bean : 则说明 exposedObject在前面的初始化方法中没有被改变。则把 earlySingletonReference 赋给 exposedObject。
  • 否则 当它不需要注入原始bean 且 已为给定名称注册了依赖bean。
    • allowRawInjectionDespiteWrapping:在循环引用的情况下,是否需要注入一个原始bean实例,即使注入的bean最终被封装。 图片.png
    • hasDependentBean(beanName):是否已为给定名称注册了依赖bean。 图片.png
    • dependentBeans: 获取依赖于指定bean的所有bean的名称 图片.png
    • 创建一个长度和dependentBeans相同的 set集合,遍历 dependentBeans ,调用removeSingletonIfCreatedForTypeCheckOnly(dependentBean) : 删除给定bean名的单例实例(如果有的话),但仅当它没有用于类型检查之外的其他目的时。 图片.png
    • 当存在没有删除的 dependentBean 则把它加入到 set集合中,若集合不为null 抛出异常。

6. 将bean注册为一次性的。

图片.png

  • registerDisposableBeanIfNecessary(beanName, bean, mbd):将给定的bean添加到此工厂的一次性bean列表中,注册其DisposableBean接口和/或给定的 Destroy 方法,在工厂关闭时调用(如果适用) 图片.png

    • 获取可访问的上下文
    • 判断当它不是原型模式,且需要在关闭时销毁 图片.png
      • 当它是单例模式的时候:注册一个 DisposableBean 实现来执行给定bean的所有销毁工作:DestructionAwareBeanPostProcessors, DisposableBean接口,自定义销毁方法。
      • 当它是其他模式的时候,交由自定义的scope进行销毁逻辑
  • 返回 exposedObject

猜你喜欢

转载自juejin.im/post/7033354315137810463
今日推荐