Spring Bean的建立初始化過程 原始碼分析

2021-10-05 07:04:19 字數 4753 閱讀 5899

title: spring bean的建立初始化過程–原始碼分析

date: 2020-04-20 19:59:24

tags:spring

bean的生命週期簡單來說:

bean建立—初始化----銷毀的過程

bean的建立初始化

​ 當完成了spring容器的初始化以及beandefinition的蒐集入庫後,spring就會開始一部分bean的建立與初始化。

(1)refresh()

//在spring的啟動方法refresh()中,最後會呼叫此方法,完成內部持有的beanfactory的初始化,並且完成所有的非懶載入的單例bean的例項化

finishbeanfactoryinitialization

(beanfactory)

;

(2)finishbeanfactoryinitialization(beanfactory)

//完成所有的非懶載入的單例bean的例項化

beanfactory.

preinstantiatesingletons()

;

(3)beanfactory.preinstantiatesingletons()

//首先獲取beandefinition的name集合

//在spring容器(defaultlistablebeanfactory)中會持有兩個關於beandefinition相關的集合物件

//beandefinitionmap和beandefinitionnames,乙個為map,乙個為list,這樣的目的就是為了儲存bean的註冊順序

//private final mapbeandefinitionmap = new concurrenthashmap<>(256);

//private volatile listbeandefinitionnames = new arraylist<>(256);

list

beannames =

newarraylist

<

>

(this

.beandefinitionnames)

;//遍歷集合

for(string beanname : beannames)}}

else

}}

(4)getbean(beanname)->dogetbean(beanname)

//private final mapsingletonobjects = new concurrenthashmap<>(256);

//先去singletonobjects檢視是否有已經建立了

object sharedinstance =

getsingleton

(beanname)

;//若已經建立,就獲取bean對應的物件返回

bean =

getobjectforbeaninstance

(sharedinstance, name, beanname, null)

;

(5)dogetbean(beanname)->createbean

//載入bean的class類

class<

?> resolvedclass =

resolvebeanclass

(mbd, beanname)

;//驗證以及準備需要覆蓋的方法

(6)createbean->docreatebeanif

(mbd.

issingleton()

)if()

;class<?(

);//呼叫beandefinitionpostprocessor修改bean定義

(mbd, beantype, beanname)

;//設定bean的屬性

populatebean

;//開始初始化bean

exposedobject =

initializebean

(beanname, exposedobject, mbd)

;(7)initializebean

//核心**

//執行beanpostprocessor的前置方法,遍歷得到容器中所有的beanpostprocessor;挨個執行beforeinitialization,一但返回null,跳出for迴圈,不會執行後面的beanpostprocessor.postprocessorsbeforeinitialization

;//執行自定義的一些初始化方法

invokeinitmethods

;執行自定義初始化

//執行beanpostprocessor的後置方法

;

自定義初始化方法

指定初始化和銷毀方法

//bean

public

class

catpublic

void

myinit()

public

void

mydestroy()

throws exception

}//配置類

@configuration

public

class

}

2.通過讓bean實現initializingbean(定義初始化邏輯),disposablebean(定義銷毀邏輯)

public

class

catimplements

initializingbean

, disposablebean

public

void

destroy()

throws exception

public

void

afterpropertiesset()

throws exception

}

3.@postconstruct:在bean建立完成並且屬性賦值完成,來執行初始化方法;@predestroy:在容器銷毀bean之前進行清理工作。

public

class

catimplements

@postconstruct

public

void

postconstruct()

}

4.實現beanpostprocessor介面

bean的後置處理器;

@component

public

class

mybeanpostprocessor

implements

beanpostprocessor

public object postprocessafterinitialization

(object bean, string beanname)

throws bean***ception

}

前面的3種方法是針對乙個bean定製化的初始化以及銷毀,而beanpostprocessor會對所有bean都起作用。

對於1、2來說,會在invokeinitmethods中一起處理。

(8)initializebean->invokeinitmethods

//這個方法的作用:檢查bean是否實現了initializingbean或定義了自定義init方法,如果實現了,則進行呼叫。

//執行initializingbean介面的afterpropertiesset

((initializingbean) bean)

.afterpropertiesset()

;//invokecustominitmethod執行自定義的init-method方法

string initmethodname = mbd.

getinitmethodname()

;if(stringutils.

haslength

(initmethodname)&&!

(isinitializingbean &&

"afterpropertiesset"

.equals

(initmethodname))&&

!mbd.

i***ternallymanagedinitmethod

(initmethodname)

)

(9)返回bean

堆排序建立初始堆

假設我們有乙個陣列int a 如果把這個陣列看作是完全二叉樹的順序儲存,那麼它對應圖1 1 a 完全二叉樹。所謂最大堆就是a i a 2i 1 且a i a 2i 2 i在此處對應0 5 這個描述即第四步的結果。也就是說我們把陣列a經過4步調整,最終構建出了它的最大堆,如圖1 1 d 另外需要說明的...

建立初始上下文

initialcontext類實現context介面,呼叫其構造方法便可建立初始上下文 即搜尋請求物件的起始點 建立初始上下文需要設定以下兩個環境屬性 上下文工廠物件spi context.initial context factory,指定要使用哪個具體服務提供程式。連線字串context.pro...

Spark程式設計 建立初始RDD

有幾種建立初始 rdd 的方式 1.通過scala 集合建立 rdd 使用sparkcontext的parallelize方法,為scala集合的資料指定分片數,儲存到記憶體中。例如 sc.parallelize list 1,2,3 2 對list 1,2,3 進行並行化,並行度為2 把scala...