1. 程式人生 > >Spring學習筆記之啟動

Spring學習筆記之啟動

spring 原理 啟動分析

技術分享

今天,以ClassPathXmlApplicationContext為例來看一下,Spring啟動的時候都做了什麽

技術分享

技術分享

重點看refresh()方法

refresh()方法是在AbstractApplicationContext類中定義的

ClassPathXmlApplicationContext間接繼承AbstractApplicationContext

技術分享

這裏面每一行代碼的註釋都寫得很清楚我就不廢話了,一行一行往下看

第1步、準備刷新上下文(PS:就不細看了)

第2步、獲取BeanFactory


技術分享

AbstractApplicationContext中的refreshBeanFactory()方法是一個抽象方法,咱們看一下具體實現。具體實現實在AbstractRefreshableApplicationContext類中。


技術分享

可以看到,如果Bean工廠存在,則銷毀,然後重新創建,不存在,則新建。

技術分享

可以看到,新創建的Bean工廠是new了一個DefaultListableBeanFactory。

有了Bean工廠以後,接下來加載Bean定義。

本示例中loadBeanDefinitions()方法是在AbstractXmlApplicationContext類中定義的。

AbstractXmlApplicationContext間接繼承AbstractRefreshableApplicationContext,同時,也是ClassPathXmlApplicationContext的直接父類。

技術分享

至於,它到底是怎麽加載,怎麽解析的,這裏就不細說了,很復雜

技術分享

總之呢,到此為止,BeanFactory也獲取到了,Bean定義也加載了。

接下來,回到refresh()

第3步、準備BeanFactory

技術分享

這裏,對傳入的BeanFactory做了一系列配置,比如,類加載器,表達式解析器,BeanPostProcessor。反正,到此為止,BeanFactory已經創建並配置完成,接下來第4步調用postProcessBeanFactory()方法,這個方法是為子類預留的,就是一個後置回調,允許子類在BeanFactory初始化之後做一些事情。

第5步、實例化並調用所有已經在BeanFactory中註冊了的BeanFactoryPostProcessor

技術分享

技術分享

技術分享


這裏補充一點,DefaultListableBeanFactory是實現了BeanDefinitionRegistry接口的。

技術分享

技術分享

第6步、實例化並且調用所有已經註冊的BeanPostProcessor(PS:註意,是BeanPostProcessor,而不是BeanFactoryPostProcessor,BeanFactoryPostProcessor是在上一步中完成的。從這裏我們也可以看出BeanFactoryPostProcessor和BeanPostProcessor的執行順序。)

技術分享

技術分享

技術分享

這裏,從Bean定義中找到所有BeanPostProcessor類型的定義然後註冊他們

第7步、初始化Message Resource

第8步、初始化時間廣播器

第9步、初始化子類中其它的Bean,這裏為子類留了一個口子

第10步、註冊監聽器

第11步、實例化所有的單例的Bean(PS:就是scope=singleton的Bean)

技術分享

接下來,看看DefaultListableBeanFactory是怎麽實現的

技術分享


重點看getBean()方法

技術分享

接著往下看doGetBean()

技術分享

看到有一個createBean方法

技術分享

技術分享

技術分享


前面,費了那麽大的勁就是做一些校驗啊之類的,最終獲得了RootBeanDefinition,有了這個東西之後就可以實例化了。

在上面的createBeanInstance方法中,

(1)如果這個類不是public的話,拋異常

(2)這個Bean的定義中有工廠方法,則使用它自帶的工廠方法實例化

(3)如果需要自動裝配,就用構造器裝配實例化

(4)如果都不是,就用普通的方式實例化,其實就是用默認的構造器實例化

技術分享

實例化之前,這裏要獲取實例化的策略。

那麽,有哪些策略呢?

技術分享

技術分享

技術分享


這裏,我們可以清楚的看到,默認的策略是Cglib

用Cglib返回的是代理對象

另外,還有一種就是普通的用默認構造方法實例化,這種返回的是真實對象。

接下來,還有最後一步

第12步、初始化LifecycleProcessor,並調用其onRefresh()方法,然後發布ContextRefreshedEvent事件


到此為止,AbstractApplicationContext的refresh()方法算是講完了。

下面總結一下:

第1步、準備刷新

第2步、加載Bean定義,並獲取BeanFactory,這裏獲取的是DefaultListableBeanFactory

第3步、配置BeanFactory,包括配置類加載器、配置BeanPostProcessor

第4步、調用postProcessBeanFactory()方法,這個方法是給子類預留的

第5步、實例化並調用所有註冊的BeanFactoryPostProcessor

第6步、實例化並調用所有註冊的BeanPostProcessor

第7步、初始化message resource

第8步、初始化事件廣播器

第9步、調用onRefresh()方法,這是一個模板方法,是給子類預留的

第10步、註冊監聽器

第11步、完成BeanFactory的初始化,並且實例化所有的單例(scope=singleton)Bean

第12步、初始化LifecycleProcessor,並調用其onRefresh()方法,然後發布ContextRefreshedEvent事件


到此結束!!!

最後,補充一個

技術分享


本文出自 “十裏稻花香” 博客,請務必保留此出處http://5880861.blog.51cto.com/5870861/1970641

Spring學習筆記之啟動