javascript
关于Spring中IOC容器和AOP协同工作的原理理解
1、在詳細介紹 IOC 容器的工作原理前,這里先介紹一下實現 IOC 所用到的一些輔助類,包括BeanDefinition、BeanReference、PropertyValues、PropertyValue。按照順序先從 BeanDefinition 開始介紹。BeanDefinition從字面意思上翻譯成中文就是 “Bean 的定義”。從翻譯結果中就可以猜出這個類的用途,即根據 Bean 配置信息生成相應的 Bean 詳情對象。
圖2 根據 bean 配置生成 BeanDefinition
看完上圖就對 BeanDefinition 的用途有了更進一步的認識。接下來我們來說說上圖中的 ref 對應的 BeanReference 對象。BeanReference 對象保存的是 bean 配置中 ref 屬性對應的值,在后續 BeanFactory 實例化 bean 時,會根據 BeanReference 保存的值去實例化 bean 所依賴的其他 bean。接下來說說 PropertyValues 和 PropertyValue 這兩個長的比較像的類,首先是PropertyValue。PropertyValue 中有兩個字段 name 和 value,用于記錄 bean 配置中的標簽的屬性值。然后是PropertyValues,PropertyValues 從字面意思上來看,是 PropertyValue 復數形式,在功能上等同于 List。那么為什么 Spring 不直接使用 List,而自己定義一個新類呢?答案是要獲得一定的控制權,看下面的代碼:
public class PropertyValues {private final List<PropertyValue> propertyValueList = new ArrayList<PropertyValue>();public void addPropertyValue(PropertyValue pv) {// 在這里可以對參數值 pv 做一些處理,如果直接使用 List,則就不行了this.propertyValueList.add(pv);}public List<PropertyValue> getPropertyValues() {return this.propertyValueList;}}XML的解析過程:
BeanFactory 初始化時,會根據傳入的 xml 配置文件路徑加載并解析配置文件。但是加載和解析 xml 配置文件這種臟活累活,BeanFactory 可不太愿意干,它只想高冷的管理容器中的 bean。于是 BeanFactory 將加載和解析配置文件的任務委托給專職人員 BeanDefinitionReader 的實現類 XmlBeanDefinitionReader 去做。那么 XmlBeanDefinitionReader 具體是怎么做的呢?
(1)將 xml 配置文件加載到內存中
(2)獲取根標簽下所有的標簽
(3)遍歷獲取到的標簽列表,并從標簽中讀取 id,class 屬性
(4)創建 BeanDefinition 對象,并將剛剛讀取到的 id,class 屬性值保存到對象中
(5)遍歷標簽下的標簽,從中讀取屬性值,并保持在 BeanDefinition 對象中
(6)將 <id, BeanDefinition> 鍵值對緩存在 Map 中,留作后用
(7)重復3、4、5、6步,直至解析結束
注冊 BeanPostProcessor:
BeanPostProcessor 接口是 Spring 對外拓展的接口之一,其主要用途提供一個機會,讓開發人員能夠插手 bean 的實例化過程。通過實現這個接口,我們就可在 bean 實例化時,對bean 進行一些處理。比如,我們所熟悉的 AOP 就是在這里將切面邏輯織入相關 bean 中的。正是因為有了 BeanPostProcessor 接口作為橋梁,才使得 AOP 可以和 IOC 容器產生聯系。
XmlBeanDefinitionReader 在完成解析工作后,BeanFactory 會將它解析得到的 <id, BeanDefinition> 鍵值對注冊到自己的 beanDefinitionMap 中。BeanFactory 注冊好 BeanDefinition 后,就立即開始注冊 BeanPostProcessor 相關實現類。這個過程比較簡單:
(1)根據 BeanDefinition 記錄的信息,尋找所有實現了 BeanPostProcessor 接口的類。
(2)實例化 BeanPostProcessor 接口的實現類
(3)將實例化好的對象放入 List中
(4)重復2、3步,直至所有的實現類完成注冊
getBean 過程解析
在完成了 xml 的解析、BeanDefinition 的注冊以及 BeanPostProcessor 的注冊過程后。BeanFactory 初始化的工作算是結束了,此時 BeanFactory 處于就緒狀態,等待外部程序的調用。
外部程序一般都是通過調用 BeanFactory 的 getBean(String name) 方法來獲取容器中的 bean。BeanFactory 具有延遲實例化 bean 的特性,也就是等外部程序需要的時候,才實例化相關的 bean。這樣做的好處是比較顯而易見的,第一是提高了 BeanFactory 的初始化速度,第二是節省了內存資源。下面我們就來詳細說說 bean 的實例化過程:
Spring? Bean的實例化過程:
BeanFactory 的生命流程:
(1)BeanFactory 加載 Bean 配置文件,將讀到的 Bean 配置封裝成 BeanDefinition 對象
(2)將封裝好的 BeanDefinition 對象注冊到 BeanDefinition 容器中
(3)注冊 BeanPostProcessor 相關實現類到 BeanPostProcessor 容器中
(4)BeanFactory 進入就緒狀態
(5)外部調用 BeanFactory 的 getBean(String name) 方法,BeanFactory 著手實例化相應的 bean
(6)重復步驟 3 和 4,直至程序退出,BeanFactory 被銷毀
轉載于:https://www.cnblogs.com/BaoZiY/p/11376108.html
總結
以上是生活随笔為你收集整理的关于Spring中IOC容器和AOP协同工作的原理理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手动实现SPring中的AOP(2)
- 下一篇: Java基础整理