概述: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();}