Spring源码版本:5.3.30
Spring中所有的getBean()
方法最终都是调用了doGetBean()
方法,不同getBean()之间的差异主要是调用doGetBean()
方法时入参的差异。通过阅读doGetBean()
方法,我们可以了解到Spring通过beanName
或bean类型
获取或创建一个Bean的整体流程。
protected <T> T doGetBean(final String name,
@Nullable final Class<T> requiredType,
@Nullable final Object[] args,
boolean typeCheckOnly) throws BeansException {
}
-
转换 beanName
:将入参中的name转换成beanName
Spring中一个Bean有且仅有一个
beanName
和多个bean别名
,在获取或者创建Bean的时候,Spring都会将bean别名
转换成beanName
,存储bean别名
和beanName
的数据结构是:Map<String, String> aliasMap
-
通过 beanName
从三级缓存中获取单例Bean。若获取到则跳3
,未获取到则跳4
用
beanName
从三级缓存中尝试获取Bean实例
一级缓存 Map<String, Object> singletonObjects
:成品二级缓存 Map<String, Object> earlySingletonObjects
:半成品三级缓存 Map<String, ObjectFactory<?>> singletonFactories
:创建Bean的工厂方法
-
处理FactoryBean相关内容,获取并返回最终对象
从三级缓存中获取到的对象并不一定是最终对象,由于FactoryBean的存在,从三级缓存中获取的FactoryBean实例,需要调用其
getObject()
方法并返回
-
若是存在正在创建的原型Bean,则直接抛出异常 -
从父BeanFactory尝试获取Bean,若能够获取到直接返回 -
标记Bean已经被创建
该
beanName
会记录到Set<String> alreadyCreated
,并且清除Map<String, RootBeanDefinition> mergedBeanDefinitions
中的合并后的BeanDefinition
-
通过 beanName
获取合并后的BeanDefinition
合并后的
BeanDefinition
会记录到Map<String, RootBeanDefinition> mergedBeanDefinitions
-
校验合并后 BeanDefinition
这里很简单,判断是否为抽象,若是立刻抛出异常
-
校验 DependOn
,并依次获取DependOn
的Bean
这里会进行循环依赖判断,主要通过
Map<String, Set<String>> dependentBeanMap
,该结构记录某个beanName
(key)被哪些bean(value)所依赖。
-
通过BeanDefinition中的标识,来进行单例、原型或其他作用域类型的Bean实例获取 -
类型转换
获取Bean时通过
byName方式
获取,入参中可能存在类型限制requiredType
,因此可能需要类型转换,于是用到了TypeConverter
(Spring中类型转换工具)尝试转换
原文始发于微信公众号(溪溪技术笔记):Spring源码阅读-doGetBean流程
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207193.html