Spring IOC源碼分析2——整體流程

1.整體流程概覽

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        register(annotatedClasses);
        refresh();
    }
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

2.具體各步驟的工作

2.1艾疟、prepareRefresh()

刷新前的預(yù)處理

1)initPropertySources()初始化一些屬性設(shè)置;子類自定義個性化的屬性設(shè)置方法嫁乘;
2)getEnvironment().validateRequiredProperties();檢驗(yàn)屬性的合法等
3)earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();保存容器中的一些早期的事件;

2.2 obtainFreshBeanFactory()

獲取BeanFactory

1)refreshBeanFactory();刷新【創(chuàng)建】BeanFactory里覆;
110行:創(chuàng)建了一個this.beanFactory = new DefaultListableBeanFactory();
設(shè)置id;
2)getBeanFactory();返回剛才GenericApplicationContext創(chuàng)建的BeanFactory對象互订;
3)將創(chuàng)建的BeanFactory【DefaultListableBeanFactory】返回叠赦;

2.3 prepareBeanFactory(beanFactory)

BeanFactory的預(yù)準(zhǔn)備工作(以上創(chuàng)建了beanFactory,現(xiàn)在對BeanFactory對象進(jìn)行一些設(shè)置屬性)
1)設(shè)置BeanFactory的類加載器、支持表達(dá)式解析器...
2)添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)設(shè)置忽略的自動裝配的接口EnvironmentAware界斜、EmbeddedValueResolverAware仿耽、xxx;
4)注冊可以解析的自動裝配各薇;我們能直接在任何組件中自動注入:
BeanFactory项贺、ResourceLoader、ApplicationEventPublisher峭判、ApplicationContext
5)添加BeanPostProcessor【ApplicationListenerDetector】
6)添加編譯時的AspectJ开缎;
7)給BeanFactory中注冊一些能用的組件;
environment【ConfigurableEnvironment】林螃、
systemProperties【Map<String, Object>】奕删、
systemEnvironment【Map<String, Object>】

2.4、postProcessBeanFactory(beanFactory)

BeanFactory準(zhǔn)備工作完成后進(jìn)行的后置處理工作

1)子類通過重寫這個方法來在BeanFactory創(chuàng)建并預(yù)準(zhǔn)備完成以后做進(jìn)一步的設(shè)置

2.5疗认、invokeBeanFactoryPostProcessors(beanFactory)

執(zhí)行BeanFactoryPostProcessor的方法
BeanFactoryPostProcessor:BeanFactory的后置處理器完残。在BeanFactory標(biāo)準(zhǔn)初始化之后執(zhí)行的;
兩個接口:BeanFactoryPostProcessor横漏、BeanDefinitionRegistryPostProcessor

1)先執(zhí)行BeanDefinitionRegistryPostProcessor
?1-1)83行:獲取所有的BeanDefinitionRegistryPostProcessor谨设;
?1-2)86行:看先執(zhí)行實(shí)現(xiàn)了PriorityOrdered優(yōu)先級接口的BeanDefinitionRegistryPostProcessor、postProcessor.postProcessBeanDefinitionRegistry(registry)
?1-3)99行:在執(zhí)行實(shí)現(xiàn)了Ordered順序接口的BeanDefinitionRegistryPostProcessor缎浇;
postProcessor.postProcessBeanDefinitionRegistry(registry)
?1-4)109行:最后執(zhí)行沒有實(shí)現(xiàn)任何優(yōu)先級或者是順序接口的BeanDefinitionRegistryPostProcessors扎拣;postProcessor.postProcessBeanDefinitionRegistry(registry)

2)再執(zhí)行BeanFactoryPostProcessor的方法
?2-1)139行:獲取所有的BeanFactoryPostProcessor
?2-2)147行:看先執(zhí)行實(shí)現(xiàn)了PriorityOrdered優(yōu)先級接口的BeanFactoryPostProcessor、postProcessor.postProcessBeanFactory()
?2-3)167行:在執(zhí)行實(shí)現(xiàn)了Ordered順序接口的BeanFactoryPostProcessor;postProcessor.postProcessBeanFactory()
?2-4)175行:最后執(zhí)行沒有實(shí)現(xiàn)任何優(yōu)先級或者是順序接口的BeanFactoryPostProcessor二蓝;postProcessor.postProcessBeanFactory()

2.6誉券、registerBeanPostProcessors(beanFactory)

注冊BeanPostProcessor(Bean的后置處理器)【 intercept bean creation】
不同接口類型的BeanPostProcessor;在Bean創(chuàng)建前后的執(zhí)行時機(jī)是不一樣的
?BeanPostProcessor刊愚、
?DestructionAwareBeanPostProcessor踊跟、
?InstantiationAwareBeanPostProcessor、(AOP和事務(wù))
?SmartInstantiationAwareBeanPostProcessor百拓、
?MergedBeanDefinitionPostProcessor【internalPostProcessors】琴锭、

1)189行:獲取所有的 BeanPostProcessor;后置處理器都默認(rèn)可以通過PriorityOrdered、Ordered接口來執(zhí)行優(yōu)先級
2)204行:先注冊PriorityOrdered優(yōu)先級接口的BeanPostProcessor衙传;把每一個BeanPostProcessor决帖;添加到BeanFactory中beanFactory.addBeanPostProcessor(postProcessor);
3)224行:再注冊O(shè)rdered接口的
4)236行:最后注冊沒有實(shí)現(xiàn)任何優(yōu)先級接口的
5)最終注冊MergedBeanDefinitionPostProcessor;
6)注冊一個ApplicationListenerDetector蓖捶;來在Bean創(chuàng)建完成后檢查是否是ApplicationListener地回,如果是applicationContext.addApplicationListener((ApplicationListener<?>) bean);

2.7、initMessageSource()

初始化MessageSource組件(做國際化功能俊鱼;消息綁定刻像,消息解析)

1)718行:獲取BeanFactory
2)719行:看容器中是否有id為messageSource的,類型是MessageSource的組件
?如果有賦值給messageSource并闲,如果沒有自己創(chuàng)建一個DelegatingMessageSource细睡;
?MessageSource:取出國際化配置文件中的某個key的值;能按照區(qū)域信息獲鹊刍稹溜徙;
3)739行:把創(chuàng)建好的MessageSource注冊在容器中,以后獲取國際化配置文件的值的時候犀填,可以自動注入MessageSource蠢壹;
?beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
?MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);以后可通過getMessage獲取

2.8、initApplicationEventMulticaster()

初始化事件派發(fā)器

1)753行:獲取BeanFactory
2)754行:從BeanFactory中獲取applicationEventMulticaster的ApplicationEventMulticaster九巡;
3)762行:如果上一步?jīng)]有配置图贸;創(chuàng)建一個SimpleApplicationEventMulticaster
4)763行:將創(chuàng)建的ApplicationEventMulticaster添加到BeanFactory中,以后其他組件直接自動注入

2.9冕广、onRefresh()

留給子容器(子類)

1)子類重寫這個方法疏日,在容器刷新的時候可以自定義邏輯;

2.10 registerListeners()

給容器中將所有項(xiàng)目里面的ApplicationListener注冊進(jìn)來

1)822行:從容器中拿到所有的ApplicationListener
2)824行:將每個監(jiān)聽器添加到事件派發(fā)器中撒汉;
?getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3)832行:派發(fā)之前步驟產(chǎn)生的事件制恍;

2.11 finishBeanFactoryInitialization(beanFactory)

初始化所有剩下的單實(shí)例bean
867行:beanFactory.preInstantiateSingletons();初始化后剩下的單實(shí)例bean

1)734行:獲取容器中的所有Bean,依次進(jìn)行初始化和創(chuàng)建對象
2)738行:獲取Bean的定義信息神凑;RootBeanDefinition
3)739行:Bean不是抽象的,是單實(shí)例的,是懶加載溉委;
    3-1)740行:判斷是否是FactoryBean鹃唯;是否是實(shí)現(xiàn)FactoryBean接口的Bean;
    3-2)760行:不是工廠Bean瓣喊。利用getBean(beanName);創(chuàng)建對象
        3-2-0)199行:getBean(beanName)坡慌; ioc.getBean();
        3-2-1)doGetBean(name, null, null, false);
        3-2-2)246行: getSingleton(beanName)先獲取緩存中保存的單實(shí)例Bean《跟進(jìn)去其實(shí)就是從MAP中拿》。如果能獲取到說明這個Bean之前被創(chuàng)建過(所有創(chuàng)建過的單實(shí)例Bean都會被緩存起來)
            從private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);獲取的
        3-2-3)緩存中獲取不到藻三,開始Bean的創(chuàng)建對象流程洪橘;
        3-2-4)287行:標(biāo)記當(dāng)前bean已經(jīng)被創(chuàng)建(防止多線程同時創(chuàng)建,使用synchronized)
        3-2-5)291行:獲取Bean的定義信息棵帽;
        3-2-6)295行:getDependsOn()熄求,bean.xml里創(chuàng)建person時,加depend-on="jeep,moon"是先把jeep和moon創(chuàng)建出來
            【獲取當(dāng)前Bean依賴的其他Bean;如果有按照getBean()把依賴的Bean先創(chuàng)建出來逗概;】
        3-2-7)啟動單實(shí)例Bean的創(chuàng)建流程弟晚;
            3-2-7-1)462行:createBean(beanName, mbd, args);
            3-2-7-2)490行:Object bean = resolveBeforeInstantiation(beanName, mbdToUse);讓BeanPostProcessor先攔截返回代理對象;
                【InstantiationAwareBeanPostProcessor】:提前執(zhí)行逾苫;
                先觸發(fā):postProcessBeforeInstantiation()卿城;
                如果有返回值:觸發(fā)postProcessAfterInitialization();
            3-2-7-3)如果前面的InstantiationAwareBeanPostProcessor沒有返回代理對象铅搓;調(diào)用4)
            3-2-7-4)501行:Object beanInstance = doCreateBean(beanName, mbdToUse, args);創(chuàng)建Bean
                 a)541行:【創(chuàng)建Bean實(shí)例】瑟押;createBeanInstance(beanName, mbd, args);
                    利用工廠方法或者對象的構(gòu)造器創(chuàng)建出Bean實(shí)例;
                 b)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                        調(diào)用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
                 c)578行:【Bean屬性賦值】populateBean(beanName, mbd, instanceWrapper);
                        賦值之前:
                        c-1)拿到InstantiationAwareBeanPostProcessor后置處理器星掰;
                            1305行:postProcessAfterInstantiation()多望;
                        c-2)拿到InstantiationAwareBeanPostProcessor后置處理器;
                            1348行:postProcessPropertyValues()蹋偏;
                        =====賦值之前:===
                        c-3)應(yīng)用Bean屬性的值便斥;為屬性利用setter方法等進(jìn)行賦值;
                                applyPropertyValues(beanName, mbd, bw, pvs);
                 d)【Bean初始化】initializeBean(beanName, exposedObject, mbd);
                        d-1)1693行:【執(zhí)行Aware接口方法】invokeAwareMethods(beanName, bean);執(zhí)行xxxAware接口的方法
                           BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
                        d-2)1698行:【執(zhí)行后置處理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
                           BeanPostProcessor.postProcessBeforeInitialization();
                        d-3)1702行:【執(zhí)行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
                            1)是否是InitializingBean接口的實(shí)現(xiàn)威始;執(zhí)行接口規(guī)定的初始化枢纠;
                            2)是否自定義初始化方法;
                        d-4)1710行:【執(zhí)行后置處理器初始化之后】applyBeanPostProcessorsAfterInitialization
                            BeanPostProcessor.postProcessAfterInitialization()黎棠;
                        
            3-2-7-5)將創(chuàng)建的Bean添加到緩存中singletonObjects晋渺;sharedInstance = getSingleton(beanName, ()跟進(jìn)去
              254行:addSingleton(),放到MAP中
              ioc容器就是這些Map脓斩;很多的Map里面保存了單實(shí)例Bean木西,環(huán)境信息。随静。八千。吗讶。;
4)所有Bean都利用getBean創(chuàng)建完成以后恋捆;
    檢查所有的Bean是否是SmartInitializingSingleton接口的照皆;如果是;就執(zhí)行afterSingletonsInstantiated()沸停;

2.12 finishRefresh()

完成BeanFactory的初始化創(chuàng)建工作膜毁,IOC容器就創(chuàng)建完成

1)882行:initLifecycleProcessor();初始化和生命周期有關(guān)的后置處理器;LifecycleProcessor
默認(rèn)從容器中找是否有l(wèi)ifecycleProcessor的組件【LifecycleProcessor】愤钾;如果沒有就new DefaultLifecycleProcessor()瘟滨,加入到容器;
自己也可以嘗試寫一個LifecycleProcessor的實(shí)現(xiàn)類能颁,可以在BeanFactory
?void onRefresh();
?void onClose();
2)885行:getLifecycleProcessor().onRefresh();
?拿到前面定義的生命周期處理器(BeanFactory)杂瘸;回調(diào)onRefresh();
3)888行:publishEvent(new ContextRefreshedEvent(this));發(fā)布容器刷新完成事件劲装;
4)891行:liveBeansView.registerApplicationContext(this);

3.IOC容器流程總結(jié)

  • 1.Spring容器在啟動的時候胧沫,先會保存所有注冊進(jìn)來的Bean的定義信息
    1)xml注冊bean;<bean>
    2)注解注冊Bean占业;@Service绒怨、@Component、@Bean谦疾、xxx

  • 2.Spring容器會合適的時機(jī)創(chuàng)建這些Bean
    1)用到這個bean的時候南蹂;利用getBean創(chuàng)建bean;創(chuàng)建好以后保存在容器中念恍;
    2)統(tǒng)一創(chuàng)建剩下所有的bean的時候六剥;finishBeanFactoryInitialization();

  • 3.后置處理器——BeanPostProcessor
    1)每一個bean創(chuàng)建完成峰伙,都會使用各種后置處理器進(jìn)行處理疗疟;來增強(qiáng)bean的功能;
    AutowiredAnnotationBeanPostProcessor:處理自動注入
    AnnotationAwareAspectJAutoProxyCreator:來做AOP功能瞳氓;
    ......
    增強(qiáng)的功能注解:
    AsyncAnnotationBeanPostProcessor
    ......

  • 4.事件驅(qū)動模型
    ApplicationListener策彤;事件監(jiān)聽;
    ApplicationEventMulticaster匣摘;事件派發(fā):

參考

  • 1)享學(xué)課堂James老師筆記
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末店诗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子音榜,更是在濱河造成了極大的恐慌庞瘸,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赠叼,死亡現(xiàn)場離奇詭異擦囊,居然都是意外死亡违霞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門瞬场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葛家,“玉大人,你說我怎么就攤上這事泌类。” “怎么了底燎?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵刃榨,是天一觀的道長。 經(jīng)常有香客問我双仍,道長枢希,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任朱沃,我火速辦了婚禮苞轿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逗物。我一直安慰自己搬卒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布翎卓。 她就那樣靜靜地躺著契邀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪失暴。 梳的紋絲不亂的頭發(fā)上坯门,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音逗扒,去河邊找鬼古戴。 笑死,一個胖子當(dāng)著我的面吹牛矩肩,可吹牛的內(nèi)容都是我干的现恼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蛮拔,長吁一口氣:“原來是場噩夢啊……” “哼述暂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起建炫,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤畦韭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后肛跌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艺配,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡察郁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了转唉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皮钠。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赠法,靈堂內(nèi)的尸體忽然破棺而出麦轰,到底是詐尸還是另有隱情,我是刑警寧澤砖织,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布款侵,位于F島的核電站,受9級特大地震影響侧纯,放射性物質(zhì)發(fā)生泄漏新锈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一眶熬、第九天 我趴在偏房一處隱蔽的房頂上張望妹笆。 院中可真熱鬧,春花似錦娜氏、人聲如沸拳缠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脊凰。三九已至,卻和暖如春茂腥,著一層夾襖步出監(jiān)牢的瞬間狸涌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工最岗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帕胆,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓般渡,卻偏偏與公主長得像懒豹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子驯用,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容