spring源碼分析系列4:ApplicationContext研究

  • 2019 年 10 月 12 日
  • 筆記

ApplicationContext介面

首先看一下一個最基本的上下文應該是什麼樣子
在這裡插入圖片描述
ApplicationContext介面的注釋里寫的很清楚:
一個基本applicationContext應該提供:

  • 訪問Bean的能力
  • 提供載入資源的能力
  • 發布事件的能力
  • 解析消息、支援國際化的能力

AbstractApplicationContext承上啟下

在這裡插入圖片描述

ConfigurableApplicationContext介面:

大部分上下文都實現了此介面. 此介面除了繼承了ApplicaitnContext介面的能力外. 還具有可配置上下文與生命周期管理功能.
其中最重要的是定義了refresh()方法. refresh()功能是載入配置.

AbstractApplicationContext抽象類:

大部分上下文都繼承了此類.AbstractApplicationContext可以說啟到承上啟下的作用.

從繼承圖我們看, AbstractApplicationContext實現了大部分的介面方法.
其中refresh()方法的實現.為ApplicationContext提供了載入配置的能力.

載入的什麼配置呢?
其實:所謂載入的配置大部分都是載入Bean

ApplicationContext與BeanFactory關係

上節分析了BeanFactory存儲BeanDefinition與Bean. 並且BeanFactory的createBean()方法可以將BeanDefinition創建成Bean.

要想從BeanFactory中獲取Bean,就得先有BeanDefinition. 有了BeanDefinition,還要觸發BeanDefinition到Bean的創建.

這裡就產生了兩個問題:

  • BeanDefinition從哪裡來?
  • 創建過程在哪裡觸發的?

ApplicationContext扮演的角色也就顯而易見了.

ApplicationContext初始化的核心工作是將散落在各個目錄下的各種配置形式的Bean定義,搜集起來解析成BeanDefinition併入庫到BeanFactory.然後觸發BeanDefinition創建成Bean,存到BeanFactory中

至此: 整個spring啟動的脈絡就也清晰了. 兩大塊:Bean定義的搜集+Bean的創建.

[開發人員]--標註-->[Bean定義] --搜集--> [BeanDefinition] --創建-->[Bean]

ApplicationContext重要工作

開發人員常用的標註Bean定義的方式有.

  • xml文件標註Bean定義
  • 註解標註Bean定義

ApplicationContext將這些Bean定義轉為BeanDefinition並不是那麼容易.

第一步搜集:需要把散落的Bean定義的載體找到.搜集起來.(注意,ApplicationContext搜集Bean定義的過程其實也是通過調用工具來執行的)

  • XML對應的有XmlBeanDefinitionReader 搜集器
  • 註解JavaConfig對應的有ClassPathBeanDefinitionScanner收集器

第二步解析.將XML或者JavaConfig中的標註了Bean定義的轉為BeanDefinition

第三步:擴展點.BeanFactoryPostProcessor.實現了此介面的類可以在BeanDefinition入庫到BeanFactory的這個階段中,修改BeanDefinition資訊.這也是spring留下的擴展點。

BeanDefinitionRegistryPostProcessor與BeanFactoryPostProcessor與BeanPostProcessor區別:

  • BeanFactoryPostProcessor:可以修改BeanDefinition。發生在BeanDefinition入庫到BeanFactory階段.
  • BeanDefinitionRegistryPostProcessor繼承與BeanFactoryPostProcessor:單從名字上看,我們可以看出,這個PostProcessor跟BeanDefinition註冊有關。他發生的階段比BeanFactoryPostProcessor更早,他用來註冊BeanDefinition用。實現了此介面的可以看作一個BeanDefinition掃描註冊器。
  • BeanPostProcessor: 發生在BeanDefinition創建Bean階段。

總結:

BeanDefinition是物料
Bean是成品
BeanFactory 存儲物料,存儲成品.
ApplicationContext初始化: 搜集物料,入庫到BeanFactory, 並觸發非懶載入成品的創建.
歡迎大家關注我的公眾號【源碼行動】,最新個人理解及時奉送。
在這裡插入圖片描述