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學習筆記之啟動