今天,以ClassPathXmlApplicationContext爲例來看一下,Spring啓動的時候都作了什麼
ide
重點看refresh()方法post
refresh()方法是在AbstractApplicationContext類中定義的spa
ClassPathXmlApplicationContext間接繼承AbstractApplicationContext3d
這裏面每一行代碼的註釋都寫得很清楚我就不廢話了,一行一行往下看代理
第1步、準備刷新上下文(PS:就不細看了)
對象
第2步、獲取BeanFactoryblog
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,而且lazy-init=false的Bean)
接下來,看看DefaultListableBeanFactory是怎麼實現的
這裏初始化全部非懶加載的單例Bean
重點看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,lazy-init=false)Bean
第12步、初始化LifecycleProcessor,並調用其onRefresh()方法,而後發佈ContextRefreshedEvent事件
到此結束!!!
最後,補充兩點:
第一點是onRefresh()方法
第二點是,當第一次調用getBean()方法時會觸發依賴注入,從上面的第11步中咱們能夠看到,大部分Bean在Spring啓動的時候就已經完成了依賴注入。注入是在AbstractAutowireCapableBeanFactory類的populateBean方法完成的。
第三點是,Spring對Bean的依賴關係提供了兩種方式:
(1)顯式方式:經過BeanDefinition中的屬性和構造方法,即經過構造方法的形式將依賴的Bean傳入進來
(2)自動裝配(autowiring):容器會自動使用反射查找屬性的類型和名稱,而後基於屬性的類型或者名稱來自動匹配容器中管理的Bean,從而自動地完成依賴注入。