Ioc概述以及總體加載過(guò)程

概述:Spring?ioc容器加載過(guò)程相對(duì)復(fù)雜,在閱讀源碼時(shí)候可以將其劃分為幾個(gè)小流程?和一個(gè)總體流程,這樣對(duì)源碼的閱讀以及理解會(huì)簡(jiǎn)單很多,大體如下:

ioc容器創(chuàng)建主主流程

beanfactory獲取子流程

beanDefinition加載過(guò)程

bean創(chuàng)建過(guò)程

懶加載機(jī)制

循環(huán)依賴的處理

這里講述ioc容器的基礎(chǔ)知識(shí)以及總體流程

一.基礎(chǔ)知識(shí)

IoC Inversion of Control (控制反轉(zhuǎn)/反轉(zhuǎn)控制),注意它是?個(gè)技術(shù)思想,不是?個(gè)技術(shù)實(shí)現(xiàn)

描述的事情:Java開(kāi)發(fā)領(lǐng)域?qū)ο蟮膭?chuàng)建,管理的問(wèn)題

傳統(tǒng)開(kāi)發(fā)?式:?如類A依賴于類B,往往會(huì)在類A中new?個(gè)B的對(duì)象

IoC思想下開(kāi)發(fā)?式:我們不???去new對(duì)象了,?是由IoC容器(Spring框架)去幫助我們實(shí)例化對(duì)

象并且管理它,我們需要使?哪個(gè)對(duì)象,去問(wèn)IoC容器要即可

我們喪失了?個(gè)權(quán)利(創(chuàng)建、管理對(duì)象的權(quán)利),得到了?個(gè)福利(不?考慮對(duì)象的創(chuàng)建、管理等?系列

事情)

為什么叫做控制反轉(zhuǎn)?

控制:指的是對(duì)象創(chuàng)建(實(shí)例化、管理)的權(quán)利

反轉(zhuǎn):控制權(quán)交給外部環(huán)境了(spring框架、IoC容器)

?IoC和DI的區(qū)別

DI:Dependancy Injection(依賴注?)IOC和DI描述的是同?件事情,只不過(guò)?度不?樣罷了



二.高級(jí)特性

lazy-Init 延遲加載

ApplicationContext 容器的默認(rèn)?為是在啟動(dòng)服務(wù)器時(shí)將所有 singleton bean 提前進(jìn)?實(shí)例化。提前

實(shí)例化意味著作為初始化過(guò)程的?部分,ApplicationContext 實(shí)例會(huì)創(chuàng)建并配置所有的singleton

bean。lazy-init="false",?即加載,表示在spring啟動(dòng)時(shí),?刻進(jìn)?實(shí)例化。

?FactoryBean 和 BeanFactory

BeanFactory接?是容器的頂級(jí)接?,定義了容器的?些基礎(chǔ)?為,負(fù)責(zé)?產(chǎn)和管理Bean的?個(gè)??,

具體使?它下?的?接?類型,?如ApplicationContext;此處我們重點(diǎn)分析FactoryBean

Spring中Bean有兩種,?種是普通Bean,?種是??Bean(FactoryBean),F(xiàn)actoryBean可以?成

某?個(gè)類型的Bean實(shí)例(返回給我們),也就是說(shuō)我們可以借助于它?定義Bean的創(chuàng)建過(guò)程。

Bean創(chuàng)建的三種?式中的靜態(tài)?法和實(shí)例化?法和FactoryBean作?類似,F(xiàn)actoryBean使?較多,尤

其在Spring框架?些組件中會(huì)使?,還有其他框架和Spring框架整合時(shí)使?

后置處理器

Spring提供了兩種后處理bean的擴(kuò)展接?,分別為 BeanPostProcessor 和

BeanFactoryPostProcessor,兩者在使?上是有所區(qū)別的。

??初始化(BeanFactory)—> Bean對(duì)象

在BeanFactory初始化之后可以使?BeanFactoryPostProcessor進(jìn)?后置處理做?些事情

在Bean對(duì)象實(shí)例化(并不是Bean的整個(gè)?命周期完成)之后可以使?BeanPostProcessor進(jìn)?后置處

理做?些事情

注意:對(duì)象不?定是springbean,?springbean?定是個(gè)對(duì)象

SpringBean的?命周期

BeanPostProcessor:

BeanPostProcessor是針對(duì)Bean級(jí)別的處理,可以針對(duì)某個(gè)具體的Bean

該接?提供了兩個(gè)?法,分別在Bean的初始化?法前和初始化?法后執(zhí)?,具體這個(gè)初始化?法指的是什么?法,類似我們?cè)诙xbean時(shí),定義了init-method所指定的?法,定義?個(gè)類實(shí)現(xiàn)了BeanPostProcessor,默認(rèn)是會(huì)對(duì)整個(gè)Spring容器中所有的bean進(jìn)?處理。如果要對(duì)具體的某個(gè)bean處理,可以通過(guò)?法參數(shù)判斷,兩個(gè)類型參數(shù)分別為Object和String,第?個(gè)參數(shù)是每個(gè)bean的實(shí)例,第?個(gè)參數(shù)是每個(gè)bean的name或者id屬性的值。所以我們可以通過(guò)第?個(gè)參數(shù),來(lái)判斷我們將要處理的具體的bean。

注意:處理是發(fā)?在Spring容器的實(shí)例化和依賴注?之后。

BeanFactoryPostProcessor

beanFactory級(jí)別的處理,是針對(duì)整個(gè)Bean的??進(jìn)?處理,

BeanDefinition對(duì)象:我們?cè)?XML 中定義的 bean標(biāo)簽,Spring 解析 bean 標(biāo)簽成為?個(gè) JavaBean,

這個(gè)JavaBean 就是 BeanDefinition

注意:調(diào)? BeanFactoryPostProcessor ?法時(shí),這時(shí)候bean還沒(méi)有實(shí)例化,此時(shí) bean 剛被解析成

BeanDefinition對(duì)象

三.ioc容器加載過(guò)程

3.1Spring IoC的容器體系

? IoC容器是Spring的核?模塊,是抽象了對(duì)象管理、依賴關(guān)系管理的框架解決?案。Spring 提供了很多的容器,其中 BeanFactory 是頂層容器(根容器),不能被實(shí)例化,它定義了所有 IoC 容器 必須遵從的?套原則,具體的容器實(shí)現(xiàn)可以增加額外的功能,?如我們常?到的ApplicationContext,其下更具體的實(shí)現(xiàn)ClassPathXmlApplicationContext 包含了解析 xml 等?系列的內(nèi)容.其中beanfactory提供了主體方法,其他接口分別實(shí)現(xiàn)他的同時(shí)又有自己相對(duì)應(yīng)的一些擴(kuò)展方法? 將相類似的功能分別放在不同接口?避免了大量重寫(xiě)方法的困擾



3.2Spring IoC容器初始化主流程


流程圖

Spring IoC 容器初始化的關(guān)鍵環(huán)節(jié)就在 AbstractApplicationContext#refresh() ?法中查看 refresh ?法來(lái)俯瞰容器創(chuàng)建的主體流程

大致流程如下

@Override

public void refresh()throws BeansException, IllegalStateException {

//對(duì)象鎖

? synchronized (this.startupShutdownMonitor) {

// Prepare this context for refreshing.

? ? ? /**

? ? ? * 刷新前做的事情

? ? ? * 設(shè)置容器的啟動(dòng)開(kāi)始時(shí)間,開(kāi)啟活躍狀態(tài) 撤銷關(guān)閉狀態(tài)

? ? ? * 驗(yàn)證環(huán)境信息中一些必要的屬性

? ? ? */

? ? ? prepareRefresh();

? ? ? // Tell the subclass to refresh the internal bean factory.

? ? ? /**

? ? ? * 獲取beanFactory

? ? ? * 加載Bean definition并注冊(cè)到BeanDefinitionRegister中

? ? ? */

? ? ? ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

? ? ? // Prepare the bean factory for use in this context.

? ? ? /**

? ? ? * BeanFactory的準(zhǔn)備動(dòng)作 (BeanFactory的一些設(shè)置 如Context的加載類等

? ? ? */

? ? ? prepareBeanFactory(beanFactory);

? ? ? try {

// Allows post-processing of the bean factory in context subclasses.

? ? ? ? /**

? ? ? ? ? * postProcessBeanFactory進(jìn)行后續(xù)工作-->空方法 實(shí)現(xiàn)擴(kuò)展

? ? ? ? ? */

? ? ? ? postProcessBeanFactory(beanFactory);

? ? ? ? // Invoke factory processors registered as beans in the context.

? ? ? ? /**

? ? ? ? ? * 實(shí)例化BeanFactoryPostProcessor接口Bean,并調(diào)用該方法

? ? ? ? ? */

? ? ? ? invokeBeanFactoryPostProcessors(beanFactory);

? ? ? ? // Register bean processors that intercept bean creation.

? ? ? ? /**

? ? ? ? ? * 注冊(cè)BeanPostProcessors 在Bean 實(shí)例化前后執(zhí)行(此時(shí)沒(méi)有bean實(shí)例化)

*/

? ? ? ? registerBeanPostProcessors(beanFactory);

? ? ? ? // Initialize message source for this context.

? ? ? ? /**

? ? ? ? ? * 國(guó)際化

? ? ? ? ? */

? ? ? ? initMessageSource();

? ? ? ? // Initialize event multicaster for this context.

? ? ? ? /**

? ? ? ? ? * 事件分發(fā)

? ? ? ? ? */

? ? ? ? initApplicationEventMulticaster();

? ? ? ? // Initialize other special beans in specific context subclasses.

? ? ? ? /**

? ? ? ? ? *? ?類重寫(xiě)這個(gè)?法,在容器刷新的時(shí)候可以?定義邏輯

? ? ? ? ? */

? ? ? ? onRefresh();

? ? ? ? // Check for listener beans and register them.

? ? ? ? /**

? ? ? ? ? * 注冊(cè)實(shí)現(xiàn)ApplicationListeners的監(jiān)聽(tīng)器

? ? ? ? ? */

? ? ? ? registerListeners();

? ? ? ? // Instantiate all remaining (non-lazy-init) singletons.

? ? ? ? /**

? ? ? ? ? * 初始化 所有非懶加載的Bean

? ? ? ? ? * 初始化所有非懶加載的所有Bean的實(shí)例(未進(jìn)行屬性設(shè)置)

? ? ? ? ? * 設(shè)置屬性值

? ? ? ? ? * 執(zhí)行初始化方法(如afterPropertiesSet? init-method等)

? ? ? ? ? * 執(zhí)行BeanProcessor對(duì)實(shí)例進(jìn)行后置處理

? ? ? ? ? */

? ? ? ? finishBeanFactoryInitialization(beanFactory);

? ? ? ? // Last step: publish corresponding event.

? ? ? ? /**

? ? ? ? ? * 完成context的刷新。主要是調(diào)?LifecycleProcessor的onRefresh()?法,并且發(fā)布事

? ? ? ? ? * 件 (ContextRefreshedEvent

*/

? ? ? ? finishRefresh();}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容