今天介紹一下大家常見的一個單詞 context 應該怎么去理解,正確的理解它有助於我們學習 spring 以及計算機系統中的其他知識。
1. context 是什么
我們經常在編程中見到 context 這個單詞,當然每個人有每個人的理解,它被理解為:上下文、容器等等。我想說的是,context 理解為上下文最為合適。為什么呢?我以一個在計算機系統的例子來解釋一下。
在計算機系統中,進程執行時有進程上下文,如果進程在執行的過程中遇到了中斷,CPU 會從用戶態切換為內核態(當然這個過程用戶進程是感知不到的,由硬件來實現的),此時進程處於的進程上下文會被切換到中斷上下文中,從而可以根據中斷號去執行相應的中斷程序。
通過上面這個例子我們可以發現,進程在執行程序(不管是用戶程序,還是內核中的中斷程序)時,都會依賴一個上下文,這個上下文由多種數據結構組成,可以提供我們運行時需要的一些數據和保存運行時的一些數據。那其實 context 就可以理解對一個程序運行時所需要的一些數據結構的抽象表達唄。
抽象是個好東西,可以更方便的表達一些東西,更好的設計系統,但大家要想進步也不能停留在抽象層面,要去探索它的真正含義,真正對應的實體。有時間和大家聊一聊抽象應該怎么去理解。
2. spring context 是什么
回到 spring 中,spring 的 ioc 容器也是程序呀,那它的執行也肯定需要依賴一個上下文。所以大家應該理解 spring context 的意思了吧。那 spring context 既然是 spring 的上下文,按照我們上面的說法上下文會對應數據結構,那 spring context 的數據結構是什么呢?換句話說,spring context 究竟包括什么?接下來我就把這個抽象的概念給大家對應到實打實的數據結構上。
3. spring context 包括什么
主要包括:
- DefaultListableBeanFactory
這就是大家常說的 ioc 容器,它里面有很多 map、list。spring 幫我們創建的 singleton 類型的 bean 就存放在其中一個 map 中。我們定義的監聽器(ApplicationListener)也被放到一個 Set 集合中。 - BeanDefinitionRegistry
把一個 BeanDefinition 放到 beanDefinitionMap。 - AnnotatedBeanDefinitionReader
針對 AnnotationConfigApplicationContext 而言。一個 BeanDefinition 讀取器。 - 擴展點集合
存放 spring 擴展點(主要是 BeanFactoryPostProcessor、BeanPostProcessor)接口的 list 集合。
4. spring context 的生命周期
下面大家可以結合代碼這段代碼去理解 spring context 的生命周期。
public static void main(String[] args) {
// 初始化和啟動
AnnotationConfigApplicationContext acaContext = new AnnotationConfigApplicationContext(AppConfig.class);
// 運行
acaContext.getBean(ServiceA.class);
// 關閉/銷毀
acaContext.close();
}
4.1 初始化和啟動
我們平時常說的spring 啟動其實就是調用 AbstractApplicationContext#refresh 完成 spring context 的初始化和啟動過程。spring context 初始化從開始到最后結束以及啟動,這整個過程都在 refresh 這個方法中。refresh 方法剛開始做的是一些 spring context 的准備工作,也就是 spring context 的初始化,比如:創建 BeanFactory、注冊 BeanFactoryPostProcessor 等,只有等這些准備工作做好以后才去開始 spring context 的啟動。
與現實生活聯系一下,你可以把初始化理解為准備原料(對應到編程中就是創建好一些數據結構,並為這些數據結構填充點數據進去),等准備了你才能去真正造玩偶、造東西呀(對應到編程中就是執行算法)。在編程中數據結構與算法是分不開的也是這個道理呀,它們相互依賴並沒有嚴格的界限划分。
4.2 運行
spring context 啟動后可以提供它的服務的這段時間。
4.3 關閉/銷毀
不需要用 spring context ,關閉它時,其實對應到代碼上就是 acaContext.close();
5. 總結
最近又去研究了一遍 spring 源碼以及一些操作系統知識的復習,突然有感而發,寫下這篇文章。如果大家想學習 spring 源碼和操作系統的話,可以下面留言,我以后會出一系列相關的文章。
搜索微信公眾號:Java知其所以然,可免費領取某課、Java 后端面經等資源,還有統一環境(教你怎么配置一套開發環境)視頻領取。