天天看點

spring-boot源碼分析之BeanFactory · 貳

前言

BeanFactory

spring boot

的最重要的核心元件,當然也是

spring boot

非常基礎的元件,是以梳理清楚

BeanFactory

的源碼才是梳理清楚

Spring boot

源碼的關鍵。前天,我們分享了

beanDefinitionNames

beanDefinitionMap

的初始化過程,雖然過程中有涉及到

beanFactory

的相關知識點,但是關于

beanFactroy

我們還沒有正式地分析過它,關于它的初始化過程,也是一無所知,為了更系統地了解

beanFactory

,從今天開始我們開始更系統地分析

beanFactory

的相關源碼,下面我們就先來看下

BeanFactory

的初始化過程。

BeanFactory初始化

今天我們依然是從一張時序圖開始講起,下面這張時序圖就是

spring boot

容器的

BeanFactory

初始化過程,

beanFactory

初始化其實是和容器的初始化同時完成的,它也是容器初始化過程中的重要一步:

spring-boot源碼分析之BeanFactory · 貳

在上面的時序圖中,最關鍵的内容就是

AnnotationConfigServletWebServerApplicationContext

的執行個體化過程,這裡面涉及到

java

類的初始化流程:建立子類時,必須先調用父類無參構造方法,是以

AnnotationConfigServletWebServerApplicationContext

是在所有父類執行個體化完成後,才完成它自己的執行個體化過程的。下面我們就來看

AnnotationConfigServletWebServerApplicationContext

的初始化流程。

createApplicationContext

debug

的過程中,我發現

BeanFactory

在容器被建立後就已經被初始化,這也就是說

BeanFactory

其實是在

spring boot

容器建立過程中被初始化的,是以我們今天主要就是研究容器建立過程,也就是

createApplicationContext()

方法:

spring-boot源碼分析之BeanFactory · 貳

關于

createApplicationContext

這個方法,我們前面已經展示過了,它的作用就是通過反射建立容器執行個體:

spring-boot源碼分析之BeanFactory · 貳

AnnotationConfigServletWebServerApplicationContext執行個體化

通過跟蹤代碼,最終可以确認,調用的是

AnnotationConfigServletWebServerApplicationContext

無參構造方法:

spring-boot源碼分析之BeanFactory · 貳

是以下面就是對

AnnotationConfigServletWebServerApplicationContext

的執行個體化,由于容器這塊繼承關系比較複雜,是以執行個體化順序也比較複雜。

容器執行個體化

雖然各位小夥伴可能很清楚

java

對象執行個體化過程,但是我覺得還是有必要再補充說明下。在有繼承關系的

java

對象執行個體化過程中,如果目前類繼承了父類,在執行個體化目前類時,先要調用父類的無參構造方法(就算不指定,也會隐式調用)。是以,在這裡初始

AnnotationConfigServletWebServerApplicationContext

時,會先調用它的父類無參構造方法,下面是

AnnotationConfigServletWebServerApplicationContext

的繼承關系,看起來确實很複雜:

spring-boot源碼分析之BeanFactory · 貳

在跟蹤代碼的過程中,最終我确認

BeanFactory

是在

GenericApplicationContext

的無參構造方法中完成初始化的,也就是

AnnotationConfigServletWebServerApplicationContext

父類的父類的父類:

spring-boot源碼分析之BeanFactory · 貳

是以初始化的過程就是,

AnnotationConfigServletWebServerApplicationContext

的無參構造方法中先調用

ServletWebServerApplicationContext

的無參構造方法,

ServletWebServerApplicationContext

GenericWebApplicationContext

GenericWebApplicationContext

的無參構造方法先調用

GenericApplicationContext

的無參構造方法(無限套娃)……

知識擴充

後續的調用這裡就直接省略了,因為他們和

BeanFactory

沒有關系,而且因為繼承關系過于複雜,是以這裡我們要盡可能簡單。在這裡所有的初始化操作中,調用父類構造方法始終是首先被執行的,也必須首先被執行(首先調用父類的無參構造方法),這也就是為什麼我們在寫類的有參構造方法的時候,如果父類沒有無參構造方法時,必須顯式調用父類有參構造方法,且必須放在第一行的原因:

spring-boot源碼分析之BeanFactory · 貳

總結

繼續閱讀