Spring學習筆記之啓動

wKiom1nYl-jD_XwmAAAnevpU4QE930.png

今天,以ClassPathXmlApplicationContext爲例來看一下,Spring啓動的時候都作了什麼
ide

wKiom1nYmJqj4-piAAAawDSEZ4w307.png

wKioL1nYmEygSmIBAAA0VnytlHQ615.png

重點看refresh()方法post

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

ClassPathXmlApplicationContext間接繼承AbstractApplicationContext3d

wKiom1nYmbDgNsVXAAFEofaJepk297.png

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

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

第2步、獲取BeanFactoryblog


wKiom1nYm0WQhSkjAACSbf737qs538.png

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

wKiom1nYm_iwkz4AAACcQ4U2Q50513.png

能夠看到,若是Bean工廠存在,則銷燬,而後從新建立,不存在,則新建。接口

wKiom1nYnIbQOfM3AADTazx-jy0444.png

能夠看到,新建立的Bean工廠是new了一個DefaultListableBeanFactory。事件

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

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

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

wKioL1nYncyiCJBUAADlQnWX4Eo104.png

至於,它究竟是怎麼加載,怎麼解析的,這裏就不細說了,很複雜

wKiom1nYnuGTHJ7pAABUqFAjoPw886.png

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

接下來,回到refresh()

第3步、準備BeanFactory

wKiom1nYoQaRGSIgAAGSf_jilSM940.png

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

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

wKioL1nYo_fyLRYHAADdNnf55bI457.png

wKiom1nYpEXTa5UPAAEbDTDFdLE722.png

wKiom1nYpEWD9JucAAENZEdtfvc687.png


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

wKioL1nYpPeSirYsAAArPfK9pk8993.png

wKiom1nYpUXQZFAoAAF40_jdBys489.png

第6步、實例化而且調用全部已經註冊的BeanPostProcessor(PS:注意,是BeanPostProcessor,而不是BeanFactoryPostProcessor,BeanFactoryPostProcessor是在上一步中完成的。從這裏咱們也能夠看出BeanFactoryPostProcessor和BeanPostProcessor的執行順序。)

wKioL1nYqYbiTKZvAAA-V052zNw988.png

wKioL1nYqROhKqjKAAFG9bzV0WY696.png

wKiom1nYqWHiLO8jAAFC4XMVOns865.png

這裏,從Bean定義中找到全部BeanPostProcessor類型的定義而後註冊他們

第7步、初始化Message Resource

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

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

第10步、註冊監聽器

第11步、實例化全部的單例的非懶加載的Bean(PS:就是scope=singleton,而且lazy-init=false的Bean)

wKiom1nYrpvQ9mM_AAFSZAtjMFs815.png

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

wKioL1nY5W7QpmmnAAF7o1H4Hxk728.png

wKiom1nY5dXgxC1lAABdiW2UOpg907.png


這裏初始化全部非懶加載的單例Bean

重點看getBean()方法

wKioL1nYs-iQE7yoAAAj0dnnmeY329.png

接着往下看doGetBean()

wKiom1nYtIqSGtl4AAETlLVK2gM832.png

看到有一個createBean方法

wKioL1nYuBmBKXmyAAE48Hzlaac182.png

wKioL1nY8a3Cq4EIAALGkN9DhNA811.png

wKiom1nYuZHQO6EgAAGusHyCZsE035.png

wKiom1nY8zHgs9aGAAIkFFKW_AY728.png

wKioL1nY8uPBJtAdAACSE6W0Uok714.png

前面,費了那麼大的勁就是作一些校驗啊之類的,最終得到了RootBeanDefinition,有了這個東西以後就能夠實例化了。

在上面的createBeanInstance方法中,

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

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

(3)若是須要自動裝配,就用構造器裝配實例化

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

wKioL1nYu9CwCdXoAADQ7NhHuC0966.png

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

那麼,有哪些策略呢?

wKiom1nYvYmjbP9aAAAkELzRTHE322.png

wKiom1nYvYnwn75EAAAycONNf5I487.png

wKioL1nYvTuCUDobAAEENUJAF3c292.png


這裏,咱們能夠清楚的看到,默認的策略是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()方法

wKiom1nYwmbT7WSrAABJZofMre0376.png

第二點是,當第一次調用getBean()方法時會觸發依賴注入,從上面的第11步中咱們能夠看到,大部分Bean在Spring啓動的時候就已經完成了依賴注入。注入是在AbstractAutowireCapableBeanFactory類的populateBean方法完成的。

第三點是,Spring對Bean的依賴關係提供了兩種方式:

(1)顯式方式:經過BeanDefinition中的屬性和構造方法,即經過構造方法的形式將依賴的Bean傳入進來

(2)自動裝配(autowiring):容器會自動使用反射查找屬性的類型和名稱,而後基於屬性的類型或者名稱來自動匹配容器中管理的Bean,從而自動地完成依賴注入。

wKiom1nY7h_So14EAAECPoCv__I843.png

相關文章
相關標籤/搜索