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
->docreatebean
if
(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的後置方法
;
自定義初始化方法對於1、2來說,會在指定初始化和銷毀方法
2.通過讓//bean
public
class
catpublic
void
myinit()
public
void
mydestroy()
throws exception
}//配置類
@configuration
public
class
}
bean
實現initializingbean
(定義初始化邏輯),disposablebean
(定義銷毀邏輯)3.public
class
catimplements
initializingbean
, disposablebean
public
void
destroy()
throws exception
public
void
afterpropertiesset()
throws exception
}
@postconstruct
:在bean
建立完成並且屬性賦值完成,來執行初始化方法;@predestroy
:在容器銷毀bean
之前進行清理工作。4.實現public
class
catimplements
@postconstruct
public
void
postconstruct()
}
beanpostprocessor
介面
bean
的後置處理器;前面的3種方法是針對乙個@component
public
class
mybeanpostprocessor
implements
beanpostprocessor
public object postprocessafterinitialization
(object bean, string beanname)
throws bean***ception
}
bean
定製化的初始化以及銷毀,而beanpostprocessor
會對所有bean
都起作用。
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...