1、spring建立的bean預設是singleton模式,會以非懶載入的方式載入,即在ioc容器初始化時,容器呼叫getbean()方法,對bean進行例項化,同時觸發依賴注入。
2、如果指定bean為prototype模式,會以懶載入的方式載入,在使用者第一次呼叫getbean()方法時觸發依賴注入。
無論是singleton模式還是prototype模式,bean的初始化與依賴注入都是通過getbean()方法觸發,基本流程如下圖:
abstractbeanfactory實現了beanfactory介面,它的getbean()直接呼叫了dogetbean()方法,真正幹活的是dogetbean()
2、dogetbean()
如果快取中能取得我們想要的bean,取得那些已經被建立過的singleton的bean,對這種bean的請求不需要重複建立。
如果快取中不能取得的話,並且有parentbeanfactory的話,就從parentbeanfactory中取。
如果parentbeanfactory中也取不到的話,那就根據bean的型別(singleton或prototype或其它)去建立我們bean,這裡呼叫了下面的createbean()方法。
3、createbean()
createbean()在abstractbeanfactory中是抽象方法,實現它的是其子類abstractautowirecapablebeanfactory。
在建立bean之前,先判斷需要建立的bean是否可以例項化,這個類是否可以通過類裝載器來載入。如果配置了postprocessor,那麼這裡返回建立bean的**物件。如果沒有配置postprocessor,就呼叫子方法docreatebean()去建立bean。
4、docreatebean()
如果是單例模式,還會向容器中快取物件,防止迴圈引用。
呼叫populatebean()方法,通過beandefinition,對上面生成的bean設定bean的屬性,完成依賴注入。
呼叫initializebean()方法完成bean的初始化。
5、createbeaninstance()
確認要建立bean例項的類是否可以例項化。如果建構函式的引數使用了autowire的話,呼叫autowireconstructor進行例項化。如果沒有使用autowire的話,用instantiatebean進行例項化。
6、instantiatebean()
用cglib對bean進行例項化。主要是呼叫bean的建構函式。
7、populatebean()
9、initializebean()
先後執行beanpostprocessor介面的前置處理(postprocessbeforeinitialization)、初始化邏輯、beanpostprocessor的後置處理(postprocessafterinitialization),其中aop的**物件在後置處理中建立。
getbean() --> 呼叫bean的建構函式 --> 依賴注入 --> bean初始化前置方法 --> bean初始化 --> bean初始化後置方法
在bean的建立和物件依賴注入的過程中,需要通過beandefinition中的資訊來遞迴地完成依賴注入。以getbean()方法為入口,通過遞迴,一層一層地完成bean的建立和注入,直到最後完成當前bean的建立。有了這個頂層bean的建立和對它的屬性依賴注入的完成,意味首和前當bean相關的整個依賴鏈的注入也完成了。
在bean建立和依賴注入完成以後,ioc容器中已經建立起一系列依靠依賴關係聯絡起來的bean,通過ioc容器的相關介面和方法,可以非常方便地供上層應用使用了。
Spring DI 依賴注入
實體類computer mobilephone student public class computer implements serializable public void setmainboard string mainboard public string gethdd public vo...
Spring DI依賴注入
di dependency injection 依賴注入,即元件之間的依賴關係由容器在應用系統執行期來決定,也就是由容器動態地將某種依賴關係的目標物件例項注入到應用系統中的各個關聯的元件之中。簡單來說,所謂的依賴注入其實就是,在建立物件的同時或之後,如何給物件的屬性賦值。如果物件由我們自己建立,這一...
初識spring,DI依賴注入
spring的依賴注入是指在spring建立物件的過程中,將物件的依賴屬性通過配置進行注入,我們先寫個bean public class user public void setusername string username public string getpassword public voi...