Spring IOC:CreateBean環(huán)節(jié)中的流程轉(zhuǎn)換
一 . 前言
此篇文章的目的 :
- 梳理Bean 的創(chuàng)建流程 , 便于后續(xù)查找問題點
- 梳理過程中的參數(shù)情況 , 減少Debug的需求
- 梳理整體家族體系
Bean 創(chuàng)建的幾個觸發(fā)場景 :
- BeanFactory 的 #getBean(...) 方法來請求某個實例對象的時候
- 使用 ApplicationContext 容器時 , 會在啟動時立即注冊部分 Bean
二 . 流程梳理
先來看一個很常見的圖 , 來源于 @ topjava.cn/article/139…

同樣的 , 這篇的流程整理也是按照此流程 , 先看一下整個流程大綱
> 實例化過程
1 實例化Bean 對象 : Spring 容器根據(jù)實例化策略對 Bean 進(jìn)行實例化
?- 常用策略模式 , 通常包括反射和 CGLIB 動態(tài)字節(jié)碼
- SimpleInstantiationStrategy : 反射
- CglibSubclassingInstantiationStrategy : 通過 CGLIB 的動態(tài)字節(jié)碼 (默認(rèn))
- createBeanInstance(...) 方法實現(xiàn) ,返回 BeanWrapper
- BeanWrapper : 低級 Bean 基礎(chǔ)結(jié)構(gòu)的核心接口
?- 低級 Bean : 無任何屬性
- BeanWrapperImpl 對 Bean 進(jìn)行“包裹” ,用于注入Bean 屬性
|- InstantiationStrategy -> SimpleInstantiationStrategy
|- SimpleInstantiationStrategy -> CglibSubclassingInstantiationStrategy
2 注入對象屬性
|- 實例化完成后,如果該 bean 設(shè)置了一些屬性的話,則利用 set 方法設(shè)置一些屬性
3 檢測 , 激活 Aware
| -感知 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
|- 如果該 Bean 實現(xiàn)了 BeanNameAware 接口
|- 則調(diào)用 #setBeanName(String beanName) 方法
4 BeanPostProcessor 前置處理
|- 如果該 bean 實現(xiàn)了 BeanClassLoaderAware 接口
|- 則調(diào)用 setBeanClassLoader(ClassLoader classLoader) 方法。
|- 如果該 bean 實現(xiàn)了 BeanFactoryAware接口
|- 則調(diào)用 setBeanFactory(BeanFactory beanFactory) 方法
|- 如果該容器注冊了 BeanPostProcessor
|- 則會調(diào)用#postProcessBeforeInitialization
|- 完成 bean 前置處理
5 檢查 InitializingBean 和 init-method
|- 如果該 bean 實現(xiàn)了 InitializingBean 接口
|-則調(diào)用#afterPropertiesSet() 方法
|- 如果該 bean 配置了 init-method 方法,則調(diào)用其指定的方法。
6 BeanPostProcessor 后置處理
|- 初始化完成后,如果該容器注冊了 BeanPostProcessor
|- 則會調(diào)用 #postProcessAfterInitialization,完成 bean 的后置處理。
7 注冊必要的Destruction 回調(diào)
8 使用Bean
|- 對象完成初始化,開始方法調(diào)用
9 檢查 DisposableBean 和 destory-method
|- 在容器進(jìn)行關(guān)閉之前,如果該 bean 實現(xiàn)了 DisposableBean 接口
|- 則調(diào)用 #destroy() 方法
|- 在容器進(jìn)行關(guān)閉之前,如果該 bean 配置了 destroy-method
|- 則調(diào)用其指定的方法。
2.1 實例化創(chuàng)建
引言 : 誰調(diào)用的 ?
doGetBean 會有2種調(diào)用途徑 :
一種是 ApplicationContext 加載的時候 , 會初始化當(dāng)前容器需要的 Bean :
- C- SpringApplication # run
- C- SpringApplication # prepareContext
- C- SpringApplication # applyInitializers : 調(diào)用 ApplicationContextInitializer 集合 , 分別執(zhí)行對應(yīng)的 initialize
- C- ApplicationContextInitializer # initialize
- C- ConditionEvaluationReport # get
- C- AbstractBeanFactory # getBean
第二種是容器必要 Bean 加載完成后 ,refresh 時處理所有的 Bean
- C- SpringApplication # run
- C- SpringApplication # refreshContext
- C- AbstractApplicationContext # refresh()
- 此處refresh 中有多處會調(diào)用 getBean
- C- AbstractApplicationContext # invokeBeanFactoryPostProcessors
- C- AbstractApplicationContext # registerBeanPostProcessors
- C- AbstractApplicationContext # onRefresh();
- C- AbstractApplicationContext # finishBeanFactoryInitialization
- C- AbstractBeanFactory # getBean
PS : 另外還有一種就是因為依賴關(guān)系被遞歸調(diào)用的
2.1.1 doGetBean 入口
C171- AbstractBeanFactory
M171_01- getBean(String name, Class<T> requiredType)
?- 直接調(diào)用 doGetBean , 這里會根據(jù)類型不同調(diào)用不同的 getBean
doGetBean 可以分為 5 個階段
- 階段一 : 生成 beanName 后嘗試從單例緩存中獲取
- 階段二 : 單例緩存中獲取失敗后 ,嘗試 ParentBeanFactory 中獲取
- 階段三 : 依賴檢查 , 保證初始化當(dāng)前bean所依賴的bean
- 階段四 : 三種不同的類型獲得 Bean 實例 (Singleton / prototype / other)
- 階段五 : 此時 Bean 已經(jīng)準(zhǔn)備完成了 , 此處檢查所需的類型是否與實際bean實例的類型匹配 , 不符需要轉(zhuǎn)換
// 核心方法一 :
M171_02- doGetBean( String name, Class<T> requiredType,Object[] args, boolean typeCheckOnly)
// 階段一 : 生成 beanName 后嘗試從單例緩存中獲取
1- transformedBeanName 生成 beanName -> PS:M171_02_01
2- getSingleton(beanName) : 單例方式獲取一個 Bean , 循環(huán)依賴就是這個環(huán)節(jié)處理 -> -> PS:M171_02_02
IF- sharedInstance != null : 如果此時已經(jīng)生成 , 且 args 為空不需要繼續(xù)加載
- getObjectForBeanInstance(sharedInstance, name, beanName, null)
// 階段二 : 單例緩存中獲取失敗后 ,嘗試 ParentBeanFactory 中獲取
ELSE-
3- isPrototypeCurrentlyInCreation(beanName) : 如果是原型模式且存在循環(huán)依賴則拋出異常
4- getParentBeanFactory() : 檢查這個工廠中是否存在bean定義
?- 如果工廠中已經(jīng)存在了 , 會有四種情況會直接 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標(biāo)記為已經(jīng)創(chuàng)建 -> PS:M171_02_04
- RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName) + checkMergedBeanDefinition
?- RootBeanDefinition的獲取和檢查 LV171_001
// 階段三 : 依賴檢查 , 保證初始化當(dāng)前bean所依賴的bean
- 對于屬性 LV171_001:mbd , 通過 getDependsOn 獲取所有依賴
FOR- 循環(huán)所有的依賴 , 分別調(diào)用 registerDependentBean + getBean 進(jìn)行遞歸操作
// 階段四 : 三種不同的類型獲得 Bean 實例
5- 判斷 Bean 的類型不同創(chuàng)建 Bean -> PS:M171_02_05
5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance
5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance
5.3- 其他 : 主要是通過 Scope 控制域 + Prototype 流程
// 階段五 : 此時 Bean 已經(jīng)準(zhǔn)備完成了 , 此處檢查所需的類型是否與實際bean實例的類型匹配
IF- 如果實例不匹配 , 則需要轉(zhuǎn)換, 轉(zhuǎn)換后直接返回
- return getTypeConverter().convertIfNecessary(bean, requiredType)
// 如果上面沒有返回 , 則直接發(fā)返回原本的Bean
// 其他方法
M171_10- getSingleton(String beanName, ObjectFactory<?> singletonFactory) : 獲取單例 Bean
M171_20- getObject() : 這里實際是調(diào)用 FactoryBean
?- 這里會通過一個 方法回調(diào)的語法糖 , 調(diào)用 createBean , 整個就連起來了 -> M173_02
// 核心方法二 : 實例化 Bean
// 首先要知道 , 前面?zhèn)鬟^來的是什么 : TODO
M171_ - getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd)
// PS : doGetBean 在附錄中展示
2.1.2 doGetBean 補充節(jié)點
PS:M171_02_01 獲取 beanName
--> canonicalName(BeanFactoryUtils.transformedBeanName(name))
---->
C181- SimpleAliasRegistry
F181_01- Map<String, String> aliasMap
M- canonicalName(BeanFactoryUtils.transformedBeanName(name))
- 主要是從 F181_01 中獲取 alias 別名
?- PS : 這里的代碼有點意思 , 看樣子是為了解決別名鏈的問題 , 即別名對應(yīng)的還有別名 , 直到取不出來
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
// 循環(huán)獲取別名對應(yīng)的是否存在別名 , 直到獲取不到
}while (resolvedName != null);
return canonicalName;
}
PS:M171_02_03 為什么四種情況會直接返回 ?
4.1- AbstractBeanFactory : parentBeanFactory.doGetBean
4.2- args != null : parentBeanFactory.getBean(nameToLookup, args)
?- 使用顯式參數(shù)委托給父類
4.3- requiredType != null: parentBeanFactory.getBean(nameToLookup, requiredType)
?- 委托給標(biāo)準(zhǔn)的getBean方法
4.4- 都不符合 : parentBeanFactory.getBean(nameToLookup)
?- Pro2
// 這里直接返回是因為存在父 BeanFactory , 且存在 BeanDefinition , 這就意味著ParentBeanFactory 能處理 , 基于 Pro 1 的原因 , 選擇直接返回
// Pro 1 : 為什么從父工廠里面獲取 -> BeanFactory parentBeanFactory = getParentBeanFactory();
這是一個遞歸操作 , 也是仿照雙親委派的方式來處理 , 即先有父對象來加載對應(yīng)的對象
同樣的 , 當(dāng)進(jìn)入 doGet 的時候 , 默認(rèn)通過父方法去加載 , 如果父方法處理完成了 , 即加載出 Bean 了 , 就直接返回
好處呢 , 想了一下 , 可以保證每個實現(xiàn)能專注于其本身需要處理的 Bean , 而不需要關(guān)注原本就會加載的 Bean
回顧一下雙親委派的目的 : 避免重復(fù)加載 + 避免核心類篡改
// Pro 2 : 四種方式去返回的區(qū)別
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
PS:M171_02_04 對于只檢查的那樣處理有什么目的 ?
這里如果是只檢查而無需創(chuàng)建 , 會在 markBeanAsCreated 方法中做2件事
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
這樣的目的是為了即標(biāo)注方法已經(jīng)檢查成功 , 而避免走沒必要的反復(fù)流程 ,允許bean工廠為重復(fù)創(chuàng)建指定bean而優(yōu)化其緩存
--> 實際邏輯
// Step 1 : alreadyCreated 是什么 ?
Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
?- alreadyCreated 包含 至少已經(jīng)創(chuàng)建過一次的bean的名稱的 Set 集合
// Step 2 : 如何利用這個對象 ?
1 : AbstractAutowireCapableBeanFactory # getTypeForFactoryBean
?- 這里會通過這個對象校驗引用的工廠bean還不存在,那么在這里退出——不會僅僅為了獲取FactoryBean的對象類型而強(qiáng)制創(chuàng)建另一個bean
2 : clearMetadata 時 , 需要判斷是否為空
PS:M171_02_05 三種不同方式的本質(zhì)區(qū)別 ?
相同點 : 最終調(diào)用 getObjectForBeanInstance
5.1- isSingleton : getSingleton + createBean + getObjectForBeanInstance
- 首先通過 getSingleton 方法, 保證加載的唯一性
- 回調(diào) createBean 創(chuàng)建 Bean
- 通過 getObjectForBeanInstance 實例化真正的 Bean
5.2- isPrototype : beforePrototypeCreation + createBean + afterPrototypeCreation + getObjectForBeanInstance
- 仔細(xì)看就能發(fā)現(xiàn) , 沒有相關(guān)的 scope 對象控制 , 直接進(jìn)行創(chuàng)建
5.3- 其他 : 主要是通過 Scope 控制域 + Prototype 流程
- 它是 singleton 的結(jié)合體 ,
- 首先會準(zhǔn)備一個 Scope 對象用于控制 Scope 域內(nèi)的 Bean 情況
- 再調(diào)用和 Prototype 一致的流程進(jìn)行創(chuàng)建
PS:M171_02_06 sharedInstance 和 bean 的區(qū)別
這里可以看到 , 首先通過 createBean 創(chuàng)建了一個 Object 對象 sharedInstance , 又通過 getObjectForBeanInstance 生成了一個 Bean ,他們有什么本質(zhì)的區(qū)別 ?
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 創(chuàng)建的 Bean 就是一個 完整的 Bean
// 但是 ,如果它是一個FactoryBean,需要使用它來創(chuàng)建一個bean實例,除非調(diào)用者實際上想要一個對工廠的引用。
sharedInstance 中的 Bean 是已經(jīng)走完 Bean 創(chuàng)建流程的 Bean了

2.1.3 AbstractBeanFactory # createBean
C171- AbstractBeanFactory
M171_03- createBean(String beanName, RootBeanDefinition mbd, Object[] args)
P- mbd : BeanDefinition 對象 , 已經(jīng)合并了父類屬性
p- args : 用于構(gòu)造函數(shù)或者工廠方法創(chuàng)建 Bean 實例對象的參數(shù)
2.1.4 AbstractAutowireCapableBeanFactory # createBean 主流程
C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
M173_02- createBean(String beanName, RootBeanDefinition mbd,Object[] args)
?- M170_01 方法的默認(rèn)實現(xiàn)
LV173_02_01- RootBeanDefinition mbdToUse : 內(nèi)部屬性 , 用于標(biāo)識根 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); --- 創(chuàng)建對象
M173_03- createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
M173_04- resolveBeanClass : 將bean類名解析為class引用
// PS:M173_02_01 RootBeanDefinition
// 確保bean類在此時被實際解析,如果動態(tài)解析的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);
}
}
// >>>>>>> 對應(yīng) prepareMethodOverride 方法
C- AbstractBeanDefinition
M- prepareMethodOverride(MethodOverride mo)
1- ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName())
?- 獲取當(dāng)前Method Name 對應(yīng)的方法數(shù)量
2- 如果沒有對應(yīng)方法 ,拋出 BeanDefinitionValidationException
3- 如果 count = 1 , 將 Overloaded 標(biāo)記為未重載 , 在后續(xù)調(diào)用的時候,可以直接找到方法而不需要進(jìn)行方法參數(shù)的校驗
// 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) : 創(chuàng)建 Bean 對象
?- 非代理對象的 常規(guī)Bean 創(chuàng)建 , 主要節(jié)點有以下幾個
- 準(zhǔn)備 BeanWrapper : BeanWrapper 是對 Bean 的包裝
- 如果單例模型,則從未完成的 FactoryBean 緩存中刪除
- createBeanInstance(beanName, mbd, args) : 進(jìn)入Bean 創(chuàng)建流程 , 創(chuàng)建一個 Bean 的封裝 BeanWrapper
?- 這里的獲取如果是單例 , 則直接獲取 , 并且移除緩存中的對象
?- 否則調(diào)用 createBeanInstance 獲取
- instanceWrapper.getWrappedInstance();
?- 包裝的實例對象
- instanceWrapper.getWrappedClass();
?- 包裝的實例對象的類型
IF- applyMergedBeanDefinitionPostProcessors
?- 如果有后置處理 , 則在此處進(jìn)行后置處理 , synchronized 上鎖
IF- addSingletonFactory
?- 如果是單例 , 且允許+ 存在循環(huán)依賴 , 則在此處進(jìn)行單例模式的處理
- populateBean : 屬性注入操作 -> M173_30
- initializeBean : 初始化 Bean
?- 此處會進(jìn)行 Init-Method 的處理 -> PS:M173_05_03
IF- getSingleton
?- 循環(huán)依賴情況 , 則會遞歸初始依賴 bean , 此處返回的是一個用于循環(huán)處理的空對象
?- 2種情況 , 返回早期對象或者 getDependentBeans 遞歸所有的 -> PS:M173_05_01
- registerDisposableBeanIfNecessary
M173_07- prepareMethodOverrides
- 獲取所有的 Overrides , 并且依次調(diào)用 prepareMethodOverride -> M173_08
M173_08- prepareMethodOverride
- getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride)
?- Foreach 所有的 Overrides , 調(diào)用 prepareMethodOverride
M173_10- autowireByName : 根據(jù)屬性名稱,完成自動依賴注入
M173_11- autowireByType : 根據(jù)屬性類型,完成自動依賴注入
- resolveDependency -> resolveDependency
M173_12- resolveDependency : 完成了所有注入屬性的獲取
- doResolveDependency
M173_13- doResolveDependency
M173_15- applyPropertyValues : 應(yīng)用到已經(jīng)實例化的 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 源碼比較長 ,放在結(jié)尾
PS:M173_05_01 : 遞歸循環(huán)細(xì)說
在 doCreateBean 中 , 會對循環(huán)依賴進(jìn)行處理
// 循環(huán)依賴情況 , 則會遞歸初始依賴 bean , 此處返回的是一個用于循環(huán)處理的空對象
// 2種情況 , 返回早期對象或者 getDependentBeans 遞歸所有的
if (earlySingletonExposure) {
// 參考循環(huán)依賴那一章 , 這里可能會返回一個未完善的前置對象引用
// 只有存在循環(huán)依賴 , 這里才不會為空
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
// 判斷存在循環(huán)依賴
}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 返回依賴于指定bean的所有bean的名稱(如果有的話)
String[] dependentBeans = getDependentBeans(beanName);
Set<String> 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 已經(jīng)存在了 ,則說明對應(yīng)的對象已經(jīng)創(chuàng)建完成了
2 . 如果對應(yīng)的對象已經(jīng)創(chuàng)建完了了 , 其中依賴的當(dāng)前對象不是正在創(chuàng)建的對象
3 . 但是其中的屬性又不是當(dāng)前的對象 , 說明循環(huán)依賴不成立 , 依賴已經(jīng)串了
@ https://www.cnblogs.com/qinzj/p/11485018.html
M173_05 doCreateBean 源碼
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// Step 1 : 準(zhǔn)備 BeanWrapper : BeanWrapper 是對 Bean 的包裝
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 如果單例模型,則從未完成的 FactoryBean 緩存中刪除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 進(jìn)入Bean 創(chuàng)建流程 , 創(chuàng)建一個 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 : 如果有后置處理 , 則在此處進(jìn)行后置處理 , synchronized 上鎖
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException("....");
}
mbd.postProcessed = true;
}
}
// Step 3 :如果是單例 , 且允許+ 存在循環(huán)依賴 , 則在此處進(jìn)行單例模式的處理
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Step 4 : 此處會進(jìn)行 Init-Method 的處理 -> PS:M173_05_03
Object exposedObject = 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("....");
}
}
// 循環(huán)依賴情況 , 則會遞歸初始依賴 bean , 此處返回的是一個用于循環(huán)處理的空對象
// 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<String> 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;
}
總結(jié)
其中有幾個錨點 :
Step 1 : 入口
入口中主要是會統(tǒng)籌管理 , 如果緩存中有 , 則直接使用 , 如果沒有 , 則區(qū)別 Scope 分別使用不同的方式獲取一個 Bean
- C171- AbstractBeanFactory
- M171_02- doGetBean
Step 2 : 創(chuàng)建主流程
創(chuàng)建主流程就是創(chuàng)建一個完整的 Bean , 走一個 Bean 創(chuàng)建的完整周期 , 包括 process , 屬性注入 , init 初始化等等 , 這些我們在后面的文章中再詳細(xì)說說
// Step 1 :
C173- AbstractAutowireCapableBeanFactory
M173_02- createBea
// Step 2 :
C173- AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
M173_05- doCreateBean
附錄
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 階段一 : 生成 beanName 后嘗試從單例緩存中獲取
final String beanName = transformedBeanName(name);
Object bean;
// 單例方式獲取一個 Bean , 循環(huán)依賴就是這個環(huán)節(jié)處理 -> -> PS:M171_02_02
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 直接從實例化中獲取 Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 階段二 : 單例緩存中獲取失敗后
if (isPrototypeCurrentlyInCreation(beanName)) {
// 如果是原型模式且存在循環(huán)依賴則拋出異常
throw new BeanCurrentlyInCreationException(beanName);
}
// 檢查這個工廠中是否存在bean定義
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果工廠中已經(jīng)存在了 , 會有四種情況會直接 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標(biāo)記為已經(jīng)創(chuàng)建 -> PS:M171_02_04
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// RootBeanDefinition的獲取和檢查 LV171_001
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 階段三 : 依賴檢查 , 保證初始化當(dāng)前bean所依賴的bean
// 對于屬性 LV171_001:mbd , 通過 getDependsOn 獲取所有依賴
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循環(huán)所有的依賴 , 分別調(diào)用 registerDependentBean + getBean 進(jìn)行遞歸操作
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 的類型不同創(chuàng)建 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 已經(jīng)準(zhǔn)備完成了 , 此處檢查所需的類型是否與實際bean實例的類型匹配
// 如果實例不匹配 , 則需要轉(zhuǎn)換, 轉(zhuǎn)換后直接返回
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());
}
}
// 如果上面沒有返回 , 則直接發(fā)返回原本的Bean
return (T) bean;
}
參考與感謝
寫這個之前 , 還跑過去再讀了一遍 , 很感謝死磕系列開啟了 IOC 的源碼學(xué)習(xí)
以上就是Spring IOC:CreateBean環(huán)節(jié)中的流程轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于Spring IOC CreateBean的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java并發(fā)編程之JUC并發(fā)核心AQS同步隊列原理剖析
AbstractQueuedSynchronizer 簡稱 AQS,可能我們幾乎不會直接去使用它,但它卻是 JUC 的核心基礎(chǔ)組件,支撐著 java 鎖和同步器的實現(xiàn),大神 Doug Lea 在設(shè)計 JUC 包時希望能夠抽象一個基礎(chǔ)且通用的組件以支撐上層模塊的實現(xiàn),AQS 應(yīng)運而生2021-09-09
MyBatis中example.createCriteria()方法的具體使用
本文詳細(xì)介紹了MyBatis的Example工具的使用方法,包括鏈?zhǔn)秸{(diào)用指定字段、設(shè)置查詢條件、支持多種查詢方式等,還介紹了mapper的crud方法、and/or方法的使用,以及如何進(jìn)行多條件和多重條件查詢,感興趣的可以了解一下2024-10-10

