Spring Core Container 原始碼分析三:Spring Beans 初始化流程分析
前言
本文是筆者所著的 Spring Core Container 原始碼分析系列之一;
本篇文章主要試圖梳理出 Spring Beans 的初始化主流程
和相關核心程式碼邏輯;
本文轉載自本人的部落格,傷神的部落格 http://www.shangyang.me/2017/04/01/spring-core-container-sourcecode-analysis-beans-instantiating-process/
本文為作者的原創作品,轉載需註明出處;
原始碼分析環境搭建
參考 Spring Core Container 原始碼分析二:環境準備
測試用例
依然使用這個官網上的用例,來進行除錯;
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package org.shangyang.spring.container;
/**
-
-
@author shangyang
*
*/
public
class Person {
String name;
Person spouse;
public |
beans.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:p= "http://www.springframework.org/schema/p" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 傳統的方式 --> <bean name="john" class="org.shangyang.spring.container.Person"> <property name="name" value="John Doe"/> <property name="spouse" ref="jane"/> </bean> <bean name="jane" class="org.shangyang.spring.container.Person"> <property name="name" value="Jane Doe"/> </bean> </beans> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public void testApplicationContext(){ ( "resource") ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml"); Person p = context.getBean( "john", Person.class); assertEquals( "John Doe", p.getName() ); assertEquals( "Jane Doe", p.getSpouse().getName() ); } |
原始碼分析
備註,這裡只針對 Spring 容器例項化 singleton bean 的主流程進行介紹;singleton bean 在 Spring 容器中被初始化的特點是,在 Spring 容器的啟動過程中就進行初始化;
(最好的分析原始碼的方式,就是通過高屋建瓴,逐個擊破的方式;首先通過流程圖獲得它的藍圖(頂層設計圖),然後再根據藍圖上的點逐個擊破;最後才能達到融會貫通,胸有成竹的境界;所以,這裡作者用這樣的方式帶你深入剖析 Spring 容器裡面的核心點,以及相關主流程到底是如何運作的。)
主流程
本章節我們將詳細去闡述的是,Spring 容器是如何對 Singleton bean 進行初始化並註冊到當前容器的;與之相關的主要有兩個流程,
解析 bean definitions 並註冊
解析 bean definitiions 並註冊到當前的 BeanFactory 中;此步驟是在 step 1.1.1.2 obtainFreshBeanFactory 完成;更詳細的介紹參考解析並註冊 bean definitions 流程從 #1 中找到所有的已註冊的 singleton bean definitions,遍歷,例項化得到 Singleton beans;此步驟對應的是 step 1.1.1.11 finishBeanFactoryInitialization 開始進行 singleton bean 的構造過程,其後呼叫
AbstractBeanFactory#getBean(beanFactory)
方法進行構造;更詳細的介紹參考 Do Get Bean 流程。
解析並註冊 bean definitions 流程
該部分參考新的博文 Spring Core Container 原始碼分析七:註冊 Bean Definitions
Do Get Bean 流程
Do Get Bean 流程的入口是 AbstractBeanFactory#doGetBean 方法,主流程圖如下,
主流程大致為,從快取中找到是否已經例項化了該 singleton bean,如果已經例項化好了,那麼就直接返回;如果在快取中沒有找到,則將當前的 bean 封裝為 RootBeanDefinition,然後通過呼叫 DefaultSingletonBeanRegistry#getSingleton 得到初始化好的 singleton bean,然後將其註冊至快取( step 1.3.3 addSingleton ),然後再判斷是普通 bean 還是 factory bean 作必要的處理( step 1.4 getObjectForBeanInstance )後,最後返回;
RootBeanDefinition
初始化了一個 RootBeanDefinition
物件,正如其類名描述的那樣,是該 bean 的頂層描述;包含了 bean 的欄位屬性,ref屬性以及繼