一個簡單的Spring容器初始化流程詳解
前言
首先我們初始化一個最簡單的容器,用這個容器研究初始化的流程。
下面就是一個再簡單不過的IoC容器瞭,該容器包含瞭一個名為beanA的bean,我們初始化容器後,取出該Bean,並調用方法。
public class BeanA { private String testStr = "Test"; public BeanA(){ System.out.println("Running A"); } public void sayHello(){ System.out.println("I'm beanA."); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="beanA" class="cn.jirath.learn.spring.BeanA"> </bean> </beans>
@Test void testHello(){ Resource springResource=new ClassPathResource("spring-beans.xml"); BeanFactory beanFactory=new XmlBeanFactory(springResource); BeanA beanA= (BeanA) beanFactory.getBean("beanA"); beanA.sayHello(); }
雖然XmlBeanFactory已經被Spring標記為過時,但是為瞭達到我們從一個xml定義的bean信息構造一個BeanFactory的目的,勉為其難,還是先用一下233。
這段代碼很簡單,但是反映瞭我們使用IoC的一個基礎流程:
- 選擇並構建數據源
- 利用數據源構建一個容器
- 取出Bean使用
我們就先從這幾點一點點講
在開始之前,需要意識到的是:Spring作為一款優秀的面向對象的框架設計,Spring中采用瞭大量的設計模式並按照面向對象的邏輯對各個類進行設計,做到瞭各個類功能單一。
這意味著,Spring的代碼會有一種剝洋蔥的感覺,子類對雙親擴展,調用默認實現。
選擇並構建數據源
構建數據源的部分難度不大,會稍微簡單點講
這裡推薦一本書:《Spring源碼深度解析(第2版)》
看瞭Spring的設計,這是真的面向對象。
Spring一開始是使用大量的xml文件配置瞭容器。從面向對象的角度思考,為瞭方便使用,需要將各種資源都被抽象出來,先看一下他的資源類結構體系。該部分是系統最底層,在core包中
InputStreamSource封裝能返回InputStream的類,可以返回這個流。
日常開發用Spring的體系也會很便捷。
Resource體系達到瞭這樣的目的:對於不同的文件來源都有一種實現來讀取該文件,同時,擁有一個規范的接口。
現在我們有瞭Resource的設計,為瞭讀取對象,Spring提供瞭BeanDefinitionReader、ResourceLoader來從資源中提取出我們需要的資源內容。這些類的關系如下:
- Resource代表一個資源對象
- ResourceLoader將文件轉化為Resource對象
- DocumentLoader將Resource對象轉化為Document對象
- BeanDefinitionDocumentReader解析Document對象為BeanDefinitions
- BeanDefinitionReader抗瞭初始化的大梁,在new的時候會綁定一個Bean定義註冊器(DefaultListableBeanFactory實現瞭他),後面解析後會用這個註冊器註冊
這就是大致的一個邏輯,把握住這個大致的邏輯看源碼,體驗要上升不少
下面是最上方的例子啟動的大致的流程,大量的代碼在處理讀取資源的邏輯
- Resource代表一個資源對象
- Resource封裝為帶編碼格式的EncodedResource對象
- XmlBeanDefinitionReader構建Document對象
- XmlBeanDefinitionReader內部有個DocumentLoader,讀取Resource對象轉化為Document對象
- ResourceLoader將文件轉化為Resource對象
- DocumentLoader將Resource對象轉化為Document對象
- Document對象轉為Element對象
- DocumentReader讀取Element對象,將信息存儲在BeanDefinitionParserDelegate
- DocumentReader解析BeanDefinitionParserDelegate為BeanDefinitionHolder
- BeanDefinitionHolder獲取BeanDefinitions,交給register進行註冊(加鎖、放map)。
- 返回註冊的數量
這裡就是初始化的結果瞭
總結
到此這篇關於一個簡單的Spring容器初始化流程的文章就介紹到這瞭,更多相關Spring容器初始化流程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring通過<import>標簽導入外部配置文件
- Spring中Xml屬性配置的解析全過程記錄
- Java Spring框架創建項目與Bean的存儲與讀取詳解
- 分析Spring框架之設計與實現資源加載器
- Spring 控制反轉和依賴註入的具體使用