Spring源码阅读-doGetBean流程

Spring源码版本:5.3.30

Spring中所有的getBean()方法最终都是调用了doGetBean()方法,不同getBean()之间的差异主要是调用doGetBean()方法时入参的差异。通过阅读doGetBean()方法,我们可以了解到Spring通过beanNamebean类型获取或创建一个Bean的整体流程。

protected <T> doGetBean(final String name,
        @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, 
        boolean typeCheckOnly)
 throws BeansException 
{

}
Spring源码阅读-doGetBean流程
doGetBean()流程图
  1. 转换beanName:将入参中的name转换成beanName

Spring中一个Bean有且仅有一个beanName和多个bean别名,在获取或者创建Bean的时候,Spring都会将bean别名转换成beanName,存储bean别名beanName的数据结构是:Map<String, String> aliasMap

  1. 通过beanName从三级缓存中获取单例Bean。若获取到则跳3,未获取到则跳4

beanName从三级缓存中尝试获取Bean实例

  • 一级缓存Map<String, Object> singletonObjects:成品
  • 二级缓存Map<String, Object> earlySingletonObjects:半成品
  • 三级缓存Map<String, ObjectFactory<?>> singletonFactories:创建Bean的工厂方法
  1. 处理FactoryBean相关内容,获取并返回最终对象

从三级缓存中获取到的对象并不一定是最终对象,由于FactoryBean的存在,从三级缓存中获取的FactoryBean实例,需要调用其getObject()方法并返回

  1. 若是存在正在创建的原型Bean,则直接抛出异常
  2. 从父BeanFactory尝试获取Bean,若能够获取到直接返回
  3. 标记Bean已经被创建

beanName会记录到Set<String> alreadyCreated,并且清除Map<String, RootBeanDefinition> mergedBeanDefinitions中的合并后的BeanDefinition

  1. 通过beanName获取合并后的BeanDefinition

合并后的BeanDefinition会记录到Map<String, RootBeanDefinition> mergedBeanDefinitions

  1. 校验合并后BeanDefinition

这里很简单,判断是否为抽象,若是立刻抛出异常

  1. 校验DependOn,并依次获取DependOn的Bean

这里会进行循环依赖判断,主要通过 Map<String, Set<String>> dependentBeanMap,该结构记录某个beanName(key)被哪些bean(value)所依赖。

  1. 通过BeanDefinition中的标识,来进行单例、原型或其他作用域类型的Bean实例获取
  2. 类型转换

获取Bean时通过byName方式获取,入参中可能存在类型限制requiredType,因此可能需要类型转换,于是用到了TypeConverter(Spring中类型转换工具)尝试转换


原文始发于微信公众号(溪溪技术笔记):Spring源码阅读-doGetBean流程

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207193.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!