Spring IOC:CreateBean环节中的流程转换

网友投稿 251 2023-01-14

Spring IOC:CreateBean环节中的流程转换

一 . 前言

此篇文章的目的 :

梳理Bean 的创建流程 , 便于后续查找问题点

梳理过程中的参数情况 , 减少Debug的需求

梳理整体家族体系

Bean 创建的几个触发场景 :

BeanFactory 的 #getBean(...) 方法来请求某个实例对象的时候

使用 ApplicationContext 容器时 , 会在启动时立即注册部分 Bean

二 . 流程梳理

先来看一个很常见的图 , 来源于 @ topjava.cn/article/139…

同样的 , 这篇的流程整理也是按照此流程 , 先看一下整个流程大纲

> 实例化过程

1 实例化Bean 对象 : Spring 容器根据实例化策略对 Bean 进行实例化

?- 常用策略模式 , 通常包括反射和 CGLIB 动态字节码

- SimpleInstantiationStrategy : 反射

- CglibSubclassingInstantiationStrategy : 通过 CGLIB 的动态字节码 (默认)

- createBeanInstance(...) 方法实现 ,返回 BeanWrapper

- BeanWrapper : 低级 Bean 基础结构的核心接口

?- 低级 Bean : 无任何属性

- BeanWrapperImpl 对 Bean 进行“包裹” ,用于注入Bean 属性

|- InstantiationStrategy -> SimpleInstantiationStrategy

|- SimpleInstantiationStrategy -> CglibSubclassingInstantiationStrategy

2 注入对象属性

|- 实例化完成后,如果该 bean 设置了一些属性的话,则利用 set 方法设置一些属性

3 检测 , 激活 Aware

| -感知 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

|- 如果该 Bean 实现了 BeanNameAware 接口

|- 则调用 #setBeanName(String beanName) 方法

4 BeanPostProcessor 前置处理

|- 如果该 bean 实现了 BeanClassLoaderAware 接口

|- 则调用 setBeanClassLoader(ClassLoader classLoader) 方法。

|- 如果该 bean 实现了 BeanFactoryAware接口

|- 则调用 setBeanFactory(BeanFactory beanFactory) 方法

|- 如果该容器注册了 BeanPostProcessor

|- 则会调用#postProcessBeforeInitialization

|- 完成 bean 前置处理

5 检查 InitializingBean 和 init-method

|- 如果该 bean 实现了 InitializingBean 接口

|-则调用#afterPropertiesSet() 方法

|- 如果该 bean 配置了 init-method 方法,则调用其指定的方法。

6 BeanPostProcessor 后置处理

|- 初始化完成后,如果该容器注册了 BeanPostProcessor

|- 则会调用 #postProcessAfterInitialization,完成 bean 的后置处理。

7 注册必要的Destruction 回调

8 使用Bean

|- 对象完成初始化,开始方法调用

9 检查 DisposableBean 和 destory-method

|- 在容器进行关闭之前,如果该 bean 实现了 DisposableBean 接口

|- 则调用 #destroy() 方法

|- 在容器进行关闭之前,如果该 bean 配置了 destroy-method 

|- 则调用其指定的方法。

2.1 实例化创建

引言 : 谁调用的 ?

doGetBean 会有2种调用途径 :

一种是 ApplicationContext 加载的时候 , 会初始化当前容器需要的 Bean :

C- SpringApplication # run

C- SpringApplication # prepareContext

C- SpringApplication # applyInitializers : 调用 ApplicationContextInitializer 集合 , 分别执行对应的 initialize

C- ApplicationContextInitializer # initialize

C- ConditionEvaluationReport # get

C- AbstractBeanFactory # getBean

第二种是容器必要 Bean 加载完成后 ,refresh 时处理所有的 Bean

C- SpringApplication # run

C- SpringApplication # refreshContext

C- AbstractApplicationContext # refresh()

此处refresh 中有多处会调用 getBean

C- AbstractApplicationContext # invokeBeanFactoryPostProcessors

C- AbstractApplicationContext # registerBeanPostProcessors

C- AbstractApplicationContext # onRefresh();

C- AbstractApplicationContext # finishBeanFactoryInitialization

C- AbstractBeanFactory # getBean

PS : 另外还有一种就是因为依赖关系被递归调用的

2.1.1 doGetBean 入口

C171- AbstractBeanFactory

M171_01- getBean(String name, Class requiredType)

?- 直接调用 doGetBean , 这里会根据类型不同调用不同的 getBean

doGetBean 可以分为 5 个阶段

阶段一 : 生成 beanName 后尝试从单例缓存中获取

阶段二 : 单例缓存中获取失败后 ,尝试 ParentBeanFactory 中获取

阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean

阶段四 : 三种不同的类型获得 Bean 实例 (Singleton / prototype / other)

阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配 , 不符需要转换

// 核心方法一 :

M171_02- doGetBean( String name, Class requiredType,Object[] args, boolean typeCheckOnly)

// 阶段一 : 生成 beanName 后尝试从单例缓存中获取

1- transformedBeanName 生成 beanName -> PS:M171_02_01

2- getSingleton(beanName) : 单例方式获取一个 Bean , 循环依赖就是这个环节处理 -> -> PS:M171_02_02

IF- sharedInstance != null : 如果此时已经生成 , 且 args 为空不需要继续加载

- getObjectForBeanInstance(sharedInstance, name, beanName, null)

// 阶段二 : 单例缓存中获取失败后 ,尝试 ParentBeanFactory 中获取

ELSE-

3- isPrototypeCurrentlyInCreation(beanName) : 如果是原型模式且存在循环依赖则抛出异常

4- getParentBeanFactory() : 检查这个工厂中是否存在bean定义

?- 如果工厂中已经存在了 , 会有四种情况会直接 return -> PS:M171_02_03

4.1- AbstractBeanFactory : parentBeanFactory.doGetBean

4.2- args != null : parentBeanFactory.getBean(nameToLookup, args)

4.3- requiredType != null: parentBeanFactory.getBean(nameToLookup, requiredType)

4.4- 都不符合 : parentBeanFactory.getBean(nameToLookup)

- 如果为类型检查而获取实例,而不是实际使用 , 则将指定的bean标记为已经创建 -> PS:M171_02_04

- RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName) + checkMergedBeanDefinition

?- RootBeanDefinition的获取和检查 LV171_001

// 阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean

- 对于属性 LV171_001:mbd , 通过 getDependsOn 获取所有依赖

FOR- 循环所有的依赖 , 分别调用 registerDependentBean + getBean 进行递归操作

// 阶段四 : 三种不同的类型获得 Bean 实例

5- 判断 Bean 的类型不同创建 Bean -> PS:M171_02_05

5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance

5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance

5.3- 其他 : 主要是通过 Scope 控制域 + Prototype 流程

// 阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配

IF- 如果实例不匹配 , 则需要转换, 转换后直接返回

- return getTypeConverter().convertIfNecessary(bean, requiredType)

// 如果上面没有返回 , 则直接发返回原本的Bean

// 其他方法

M171_10- getSingleton(String beanName, ObjectFactory> singletonFactory) : 获取单例 Bean

M171_20- getObject() : 这里实际是调用 FactoryBean

?- 这里会通过一个 方法回调的语法糖 , 调用 createBean , 整个就连起来了 -> M173_02

// 核心方法二 : 实例化 Bean

// 首先要知道 , 前面传过来的是什么 : TODO

M171_ - getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd)

// PS : doGetBean 在附录中展示

2.1.2 doGetBean 补充节点

PS:M171_02_01 获取 beanName

--> canonicalName(BeanFactoryUtils.transformedBeanName(name))

---->

C181- SimpleAliasRegistry

F181_01- Map aliasMap

M- canonicalName(BeanFactoryUtils.transformedBeanName(name))

- 主要是从 F181_01 中获取 alias 别名

?- PS : 这里的代码有点意思 , 看样子是为了解决别名链的问题 , 即别名对应的还有别名 , 直到取不出来

public String canonicalName(String name) {

String canonicalName = name;

String resolvedName;

do {

resolvedName = this.aliasMap.get(canonicalName);

if (resolvedName != null) {

canonicalName = resolvedName;

}

// 循环获取别名对应的是否存在别名 , 直到获取不到

}while (resolvedName != null);

return canonicalName;

}

PS:M171_02_03 为什么四种情况会直接返回 ?

4.1- AbstractBeanFactory : parentBeanFactory.doGetBean

4.2- args != null : parentBeanFactory.getBean(nameToLookup, args)

?- 使用显式参数委托给父类

4.3- requiredType != null: parentBeanFactory.getBean(nameToLookup, requiredType)

?- 委托给标准的getBean方法

4.4- 都不符合 : parentBeanFactory.getBean(nameToLookup)

?- Pro2

// 这里直接返回是因为存在父 BeanFactory , 且存在 BeanDefinition , 这就意味着ParentBeanFactory 能处理 , 基于 Pro 1 的原因 , 选择直接返回

// Pro 1 : 为什么从父工厂里面获取 -> BeanFactory parentBeanFactory = getParentBeanFactory();

这是一个递归操作 , 也是仿照双亲委派的方式来处理 , 即先有父对象来加载对应的对象

同样的 , 当进入 doGet 的时候 , 默认通过父方法去加载 , 如果父方法处理完成了 , 即加载出 Bean 了 , 就直接返回

好处呢 , 想了一下 , 可以保证每个实现能专注于其本身需要处理的 Bean , 而不需要关注原本就会加载的 Bean

回顾一下双亲委派的目的 : 避免重复加载 + 避免核心类篡改

// Pro 2 : 四种方式去返回的区别

Object getBean(String name) throws BeansException;

T getBean(String name, Class requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

T getBean(Class requiredType) throws BeansException;

T getBean(Class requiredType, Object... args) throws BeansException;

PS:M171_02_04 对于只检查的那样处理有什么目的 ?

这里如果是只检查而无需创建 , 会在 markBeanAsCreated 方法中做2件事

clearMergedBeanDefinition(beanName);

this.alreadyCreated.add(beanName);

这样的目的是为了即标注方法已经检查成功 , 而避免走没必要的反复流程 ,允许bean工厂为重复创建指定bean而优化其缓存

--> 实际逻辑

// Step 1 : alreadyCreated 是什么 ?

Set alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

?- alreadyCreated 包含 至少已经创建过一次的bean的名称的 Set 集合

// Step 2 : 如何利用这个对象 ?

1 : AbstractAutowireCapableBeanFactory # getTypeForFactoryBean

?- 这里会通过这个对象校验引用的工厂bean还不存在,那么在这里退出——不会仅仅为了获取FactoryBean的对象类型而强制创建另一个bean

2 : clearMetadata 时 , 需要判断是否为空

PS:M171_02_05 三种不同方式的本质区别 ?

相同点 : 最终调用 getObjectForBeanInstance

5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance

- 首先通过 getSingleton 方法, 保证加载的唯一性

- 回调 createBean 创建 Bean

- 通过 getObjectForBeanInstance 实例化真正的 Bean

5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance

- 仔细看就能发现 , 没有相关的 scope 对象控制 , 直接进行创建

5.3- 其他 : 主要是通过 Scope 控制域 + Prototype 流程

- 它是 singleton 的结合体 ,

- 首先会准备一个 Scope 对象用于控制 Scope 域内的 Bean 情况

- 再调用和 Prototype 一致的流程进行创建

PS:M171_02_06 sharedInstance 和 bean 的区别

这里可以看到 , 首先通过 createBean 创建了一个 Object 对象 sharedInstance , 又通过 getObjectForBeanInstance 生成了一个 Bean ,他们有什么本质的区别 ?

if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, () -> {

try {

return createBean(beanName, mbd, args);

}catch (BeansException ex) {

destroySingleton(beanName);

throw ex;

}

});

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

}

// 这就涉及到 Bean 的工厂了 , 一般情况下 , createBean 创建的 Bean 就是一个 完整的 Bean

// 但是 ,如果它是一个FactoryBean,需要使用它来创建一个bean实例,除非调用者实际上想要一个对工厂的引用。

sharedInstance 中的 Bean 是已经走完 Bean 创建流程的 Bean了

2.1.3 AbstractBeanFactory # createBean

C171- AbstractBeanFactory

M171_03- createBean(String beanName, RootBeanDefinition mbd, Object[] args) 

P- mbd : BeanDefinition 对象 , 已经合并了父类属性

p- args : 用于构造函数或者工厂方法创建 Bean 实例对象的参数

2.1.4 AbstractAutowireCapableBeanFactory # createBean 主流程

C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

M173_02- createBean(String beanName, RootBeanDefinition mbd,Object[] args)

?- M170_01 方法的默认实现

LV173_02_01- RootBeanDefinition mbdToUse : 内部属性 , 用于标识根 BeanDefinition

1- Class> resolvedClass = resolveBeanClass(mbd, beanName) -> PS:M173_02_01

?- 解析获得指定 BeanDefinition 的 class 属性 -> M173_04

IF- 解析的 Class 不为 null , 且存在 BeanClass 和 BeanClassName

- new RootBeanDefinition(mbd)

- mbdToUse.setBeanClass(resolvedClass)

2- mbdToUse.prepareMethodOverrides() : 处理 Overrides 属性 -> PS:M173_02_02

- GetMethodOverrides().getOverrides()

- prepareMethodOverride(MethodOverride mo)

3- Object bean = resolveBeforeInstantiation(beanName, mbdToUse) --- 实例化的前置处理

- 如果 bean 不为 null , 则直接返回 (直接返回是因为上一步生成了一个代理类 ,AOP )

4- Object beanInstance = doCreateBean(beanName, mbdToUse, args); --- 创建对象

M173_03- createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

M173_04- resolveBeanClass : 将bean类名解析为class引用

// PS:M173_02_01 RootBeanDefinition

// 确保bean类在此时被实际解析,如果动态解析的class不能存储在共享合并bean定义中,则克隆bean定义

RootBeanDefinition mbdToUse = mbd;

Class> resolvedClass = resolveBeanClass(mbd, beanName);

if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {

mbdToUse = new RootBeanDefinition(mbd);

mbdToUse.setBeanClass(resolvedClass);

}

// PS:M173_02_02 prepareMethodOverrides 处理 Overrides

public void prepareMethodOverrides() throws BeanDefinitionValidationException {

if (hasMethodOverrides()) {

getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);

}

}

// >>>>>>> 对应 prepareMethodOverride 方法

C- AbstractBeanDefinition

M- prepareMethodOverride(MethodOverride mo)

1- ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName())

?- 获取当前Method Name 对应的方法数量

2- 如果没有对应方法 ,抛出 BeanDefinitionValidationException

3- 如果 count = 1 , 将 Overloaded 标记为未重载 , 在后续调用的时候,可以直接找到方法而不需要进行方法参数的校验

// M173_02 源码简介

M- createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

- beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);

- beanInstance = this.doCreateBean(beanName, mbdToUse, args); -> M173_05

doCreateBean 主流程

doCreate 分为几大步骤 :

C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

M173_05- doCreateBean(beanName, mbdToUse, args) : 创建 Bean 对象

?- 非代理对象的 常规Bean 创建 , 主要节点有以下几个

- 准备 BeanWrapper : BeanWrapper 是对 Bean 的包装

- 如果单例模型,则从未完成的 FactoryBean 缓存中删除

- createBeanInstance(beanName, mbd, args) : 进入Bean 创建流程 , 创建一个 Bean 的封装 BeanWrapper

?- 这里的获取如果是单例 , 则直接获取 , 并且移除缓存中的对象

?- 否则调用 createBeanInstance 获取

- instanceWrapper.getWrappedInstance();

?- 包装的实例对象

- instanceWrapper.getWrappedClass();

?- 包装的实例对象的类型

IF- applyMergedBeanDefinitionPostProcessors

?- 如果有后置处理 , 则在此处进行后置处理 , synchronized 上锁

IF- addSingletonFactory

?- 如果是单例 , 且允许+ 存在循环依赖 , 则在此处进行单例模式的处理

- populateBean : 属性注入操作 -> M173_30

- initializeBean : 初始化 Bean

?- 此处会进行 Init-Method 的处理 -> PS:M173_05_03

IF- getSingleton

?- 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象

?- 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的 -> PS:M173_05_01

- registerDisposableBeanIfNecessary

M173_07- prepareMethodOverrides

- 获取所有的 Overrides , 并且依次调用 prepareMethodOverride -> M173_08

M173_08- prepareMethodOverride

- getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride)

?- Foreach 所有的 Overrides , 调用 prepareMethodOverride

M173_10- autowireByName : 根据属性名称,完成自动依赖注入

M173_11- autowireByType : 根据属性类型,完成自动依赖注入

- resolveDependency -> resolveDependency

M173_12- resolveDependency : 完成了所有注入属性的获取

- doResolveDependency

M173_13- doResolveDependency

M173_15- applyPropertyValues : 应用到已经实例化的 bean 中

M173_50- initializeBean

// doCreateBean 核心代码流程

M- doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) : createBean 主流程

- mbd.isSingleton() : 判断后获取 BeanWrapper (ConfigurationClassPostProcessor)

- instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);

- instanceWrapper = this.createBeanInstance(beanName, mbd, args);

- this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

- this.populateBean(beanName, mbd, instanceWrapper) : 主要是属性填充

- Step 1 : bw == null&&mbd.hasPropertyValues() : BeanWrapper 空值判断

- Step 2 : this.getBeanPostProcessors().iterator() : 迭代BeanPostProcessors

- ibp.postProcessAfterInstantiation : 此处是 After

- Step 3 : 获取 PropertyValue , 并且通过 autowireByName 或者 autowireByType 注入

- Step 4 : hasInstantiationAwareBeanPostProcessors

- this.getBeanPostProcessors().iterator();

- ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);

- Step 5 :

- Step 6 : this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs) : 依赖检查

- Step 7 : this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs) :

- this.initializeBean(beanName, exposedObject, mbd);

- this.registerDisposableBeanIfNecessary(beanName, bean, mbd);

// 附录 : M173_05 doCreateBean 源码比较长 ,放在结尾

PS:M173_05_01 : 递归循环细说

在 doCreateBean 中 , 会对循环依赖进行处理

// 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象

// 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的

if (earlySingletonExposure) {

// 参考循环依赖那一章 , 这里可能会返回一个未完善的前置对象引用

// 只有存在循环依赖 , 这里才不会为空

Object earlySingletonReference = getSingleton(beanName, false);

if (earlySingletonReference != null) {

if (exposedObject == bean) {

exposedObject = earlySingletonReference;

// 判断存在循环依赖

}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {

// 返回依赖于指定bean的所有bean的名称(如果有的话)

String[] dependentBeans = getDependentBeans(beanName);

Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);

for (String dependentBean : dependentBeans) {

// 如果有被用于类型检查之外的其他目的时 ,则不可以删除 -> PS:M173_05_03

if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {

// 无需删除 , 则添加

actualDependentBeans.add(dependentBean);

}

}

// 因为上文添加 , 这里就形成依赖

if (!actualDependentBeans.isEmpty()) {

throw new BeanCurrentlyInCreationException(".....");

}

}

}

}

// PS:M173_05_03 : 什么是其他的目的 ?

removeSingletonIfCreatedForTypeCheckOnly 核心是校验 alreadyCreated

1 . 如果 alreadyCreated 已经存在了 ,则说明对应的对象已经创建完成了

2 . 如果对应的对象已经创建完了了 , 其中依赖的当前对象不是正在创建的对象

3 . 但是其中的属性又不是当前的对象 , 说明循环依赖不成立 , 依赖已经串了

@ https://cnblogs.com/qinzj/p/11485018.html

M173_05 doCreateBean 源码

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {

// Step 1 : 准备 BeanWrapper : BeanWrapper 是对 Bean 的包装

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

// 如果单例模型,则从未完成的 FactoryBean 缓存中删除

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

// 进入Bean 创建流程 , 创建一个 Bean 的封装 BeanWrapper

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

// 获取包装的实例对象

final Object bean = instanceWrapper.getWrappedInstance();

// 包装的实例对象的类型

Class> beanType = instanceWrapper.getWrappedClass();

if (beanType != NullBean.class) {

mbd.resolvedTargetType = beanType;

}

// Step 2 : 如果有后置处理 , 则在此处进行后置处理 , synchronized 上锁

synchronized (mbd.postProcessingLock) {

if (!mbd.postProcessed) {

try {

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

}

catch (Throwable ex) {

throw new BeanCreationException("....");

}

mbd.postProcessed = true;

}

}

// Step 3 :如果是单例 , 且允许+ 存在循环依赖 , 则在此处进行单例模式的处理

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&

isSingletonCurrentlyInCreation(beanName));

if (earlySingletonExposure) {

ahttp://ddSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

}

// Step 4 : 此处会进行 Init-Method 的处理 -> PS:M173_05_03

Object exposegoTXUnvdObject = bean;

try {

// Step 5 :属性注入操作 -> M173_30

populateBean(beanName, mbd, instanceWrapper);

// Step 6 : 初始化 Bean

exposedObject = initializeBean(beanName, exposedObject, mbd);

}

catch (Throwable ex) {

if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {

throw (BeanCreationException) ex;

}

else {

throw new BeanCreationException("....");

}

}

// 循环依赖情况 , 则会递归初始依赖 bean , 此处返回的是一个用于循环处理的空对象

// 2种情况 , 返回早期对象或者 getDependentBeans 递归所有的 -> PS:M173_05_01

if (earlySingletonExposure) {

Object earlySingletonReference = getSingleton(beanName, false);

if (earlySingletonReference != null) {

if (exposedObject == bean) {

exposedObject = earlySingletonReference;

}

else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {

String[] dependentBeans = getDependentBeans(beanName);

Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);

for (String dependentBean : dependentBeans) {

if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {

actualDependentBeans.add(dependentBean);

}

}

if (!actualDependentBeans.isEmpty()) {

throw new BeanCurrentlyInCreationException(".....");

}

}

}

}

// Step 7 : 注册 Bean

try {

registerDisposableBeanIfNecessary(beanName, bean, mbd);

}

catch (BeanDefinitionValidationException ex) {

throw new BeanCreationException("...");

}

return exposedObject;

}

总结

其中有几个锚点 :

Step 1 : 入口

入口中主要是会统筹管理 , 如果缓存中有 , 则直接使用 , 如果没有 , 则区别 Scope 分别使用不同的方式获取一个 Bean

- C171- AbstractBeanFactory

- M171_02- doGetBean

Step 2 : 创建主流程

创建主流程就是创建一个完整的 Bean , 走一个 Bean 创建的完整周期 , 包括 process , 属性注入 , init 初始化等等 , 这些我们在后面的文章中再详细说说

// Step 1 :

C173- AbstractAutowireCapableBeanFactory

M173_02- createBea

// Step 2 :

C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

M173_05- doCreateBean

附录

protected T doGetBean(final String name, @Nullable final Class requiredType,

@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

// 阶段一 : 生成 beanName 后尝试从单例缓存中获取

final String beanName = transformedBeanName(name);

Object bean;

// 单例方式获取一个 Bean , 循环依赖就是这个环节处理 -> -> PS:M171_02_02

Object sharedInstance = getSingleton(beanName);

if (sharedInstance != null && args == null) {

// 直接从实例化中获取 Bean

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

}

else {

// 阶段二 : 单例缓存中获取失败后

if (isPrototypeCurrentlyInCreation(beanName)) {

// 如果是原型模式且存在循环依赖则抛出异常

throw new BeanCurrentlyInCreationException(beanName);

}

// 检查这个工厂中是否存在bean定义

BeanFactory parentBeanFactory = getParentBeanFactory();

// 如果工厂中已经存在了 , 会有四种情况会直接 return -> PS:M171_02_03

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

// Not found -> check parent.

String nameToLookup = originalBeanName(name);

if (parentBeanFactory instanceof AbstractBeanFactory) {

return ((AbstractBeanFactory) parentBeanFactory).doGetBean(

nameToLookup, requiredType, args, typeCheckOnly);

}

else if (args != null) {

// Delegation to parent with explicit args.

return (T) parentBeanFactory.getBean(nameToLookup, args);

}

else if (requiredType != null) {

// No args -> delegate to standard getBean method.

return parentBeanFactory.getBean(nameToLookup, requiredType);

}

else {

return (T) parentBeanFactory.getBean(nameToLookup);

}

}

// 如果为类型检查而获取实例,而不是实际使用 , 则将指定的bean标记为已经创建 -> PS:M171_02_04

if (!typeCheckOnly) {

markBeanAsCreated(beanName);

}

try {

// RootBeanDefinition的获取和检查 LV171_001

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

// 阶段三 : 依赖检查 , 保证初始化当前bean所依赖的bean

// 对于属性 LV171_001:mbd , 通过 getDependsOn 获取所有依赖

String[] dependsOn = mbd.getDependsOn();

if (dependsOn != null) {

// 循环所有的依赖 , 分别调用 registerDependentBean + getBean 进行递归操作

for (String dep : dependsOn) {

if (isDependent(beanName, dep)) {

throw new BeanCreationException(.....);

}

registerDependentBean(dep, beanName);

try {

getBean(dep);

}

catch (NoSuchBeanDefinitionException ex) {

throw new BeanCreationException(.....);

}

}

}

// 阶段四 : 三种不同的类型获得 Bean 实例

// 判断 Bean 的类型不同创建 Bean -> PS:M171_02_05

if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, () -> {

try {

return createBean(beanName, mbd, args);

}

catch (BeansException ex) {

destroySingleton(beanName);

throw ex;

}

});

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

}

else if (mbd.isPrototype()) {

// It's a prototype -> create a new instance.

Object prototypeInstance = null;

try {

beforePrototypeCreation(beanName);

prototypeInstance = createBean(beanName, mbd, args);

}

finally {

afterPrototypeCreation(beanName);

}

bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

}

else {

String scopeName = mbd.getScope();

final Scope scope = this.scopes.get(scopeName);

if (scope == null) {

throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");

}

try {

Object scopedInstance = scope.get(beanName, () -> {

beforePrototypeCreation(beanName);

try {

return createBean(beanName, mbd, args);

}

finally {

afterPrototypeCreation(beanName);

}

});

bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

}

catch (IllegalStateException ex) {

throw new BeanCreationException(....);

}

}

}

catch (BeansException ex) {

cleanupAfterBeanCreationFailure(beanName);

throw ex;

}

}

// 阶段五 : 此时 Bean 已经准备完成了 , 此处检查所需的类型是否与实际bean实例的类型匹配

// 如果实例不匹配 , 则需要转换, 转换后直接返回

if (requiredType != null && !requiredType.isInstance(bean)) {

try {

T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);

if (convertedBean == null) {

throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

}

return convertedBean;

}

catch (TypeMismatchException ex) {

throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

}

}

// 如果上面没有返回 , 则直接发返回原本的Bean

return (T) bean;

}

参考与感谢

写这个之前 , 还跑过去再读了一遍 , 很感谢死磕系列开启了 IOC 的源码学习

-> @ topjava.cn/article/139…

以上就是Spring IOC:CreateBean环节中的流程转换的详细内容,更多关于Spring IOC CreateBean的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java面向对象之猜拳游戏
下一篇:SpringBoot项目接入Nacos的实现步骤
相关文章

 发表评论

暂时没有评论,来抢沙发吧~