在 Spring.Net 中對象初始化的方式分為兩種:
① 急切實例化,也就是說 Spring.Net 容器初始化的時候將對象先實例化出來。
② 延遲實例化,也就是說我們在調用 GetObject 方法時才實例化該對象。
Spring.Net 默認使用的 急切實例化 ( lazy-init=“false” ) 的方式來初始化對象。lazy-init=“false” 從字面上理解就是 ”不延遲實例化(急切實例化)“,而 lazy-init=“true” 就是 “延遲實例化”的意思。 只要是一個對象(通過Spring容器創建的) 沒有被顯示的設置為 lazy-init="true" ,那么 Spring.Net 容器在 被初始化的時候就將 這個對象實例化出來 。
在設置 lazy-init 的時候,猶如一把雙刃劍,設置為 延遲實例化 lazy-init=“true” 的時候我們的應用程序在啟動的時候會快一點,但是在啟動的時候就不能幫我們檢測程序錯誤了。當在調用的時候遇到錯誤,后果是不堪設想的。例如: 程序引用了一個不存在的對象定義或發生循環依賴等等。設置為延遲實例化時,則會推遲到對象實際被創建時才會執行。也就是說,如果某個對象或其依賴項無法正確創建,那么即便是容器可以正常創建,在請求這個對象時也會拋出異常。如果遺漏了本該賦值的屬性,或者所賦予的屬性值無效時,會拋出異常而導致該對象無法正確創建。這也是 IApplicationContext 使用 急切實例化 ( lazy-init=“false” ) 和 單例模式 ( singleton="ture" ) 作為默認布署方式的原因。所有對象都在實際需要前被創建,這種時間和空間上的開銷可以保證 IApplicationContext 在創建時及早發現問題。如果願意,可隨時覆蓋這一默認行為,將任意對象設置為延遲創建。
一 . 急切實例化
來看一下默認設置:急切實例化。
Objects.xml 的配置文件:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 4 <!--對象默認 設置為急切實例化 lazy-init="false" ,我們在這里顯示設置--> 5 <object id="hexu" type="CnblogLesson_4_4.Model.Person,CnblogLesson_4_4" lazy-init="false"> 6 <property name="Id" value="1"/> 7 <property name="Name" value="hexu"/> 8 <property name="IsStudent" value="false"/> 9 </object> 10 11 </objects>
為了更好的證明,Spring.Net 中 lazy-init 的效果,我們為Person.cs 添加構造函數,我們在構造函數中打印一句話: "Person對象被初始化了"。
Person.cs 代碼:
1 using System; 2 using System.Collections.Generic; 3 4 namespace CnblogLesson_4_4.Model 5 { 6 /// <summary> 7 /// 人類 8 /// </summary> 9 public class Person 10 { 11 public Person() { 12 Console.WriteLine("Person對象被初始化了"); 13 } 14 15 /// <summary> 16 /// 編號 17 /// </summary> 18 public int Id { get; set; } 19 20 /// <summary> 21 /// 人的名稱 22 /// </summary> 23 public string Name { get; set; } 24 25 /// <summary> 26 /// 是否是學生 27 /// </summary> 28 public bool IsStudent { get; set; } 29 } 30 }
我們運行程序,可以看到,斷點還在 Console.WriteLine("剛剛執行到這里!"); 這里的時候, 控制台 就打印出了 “Person對象被初始化了” 。因此可以看出,Spring.Net 對象的默認初始化行為(急切實例化),在初始化容器的時候就將 Person 對象初始化了,而並未真正等到 Person hexu1 = context.GetObject("hexu") as Person; 的調用才進行實例化。
二 . 延遲實例化
再來看一下 我們手動對對象設置 延遲實例化 ( lazy-init="true" ) 之后是什么效果。
Objects.xml 的配置文件:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 4 <!--我們手動對 對象 設置 延遲實例化 lazy-init="true" --> 5 <object id="hexu_lazyinit" type="CnblogLesson_4_4.Model.Person,CnblogLesson_4_4" lazy-init="true"> 6 <property name="Id" value="2"/> 7 <property name="Name" value="hexu"/> 8 <property name="IsStudent" value="false"/> 9 </object> 10 11 </objects>
我們運行程序,可以看到,“剛剛執行到這里!” 這句話被輸出之前,調用了 hexu 對象 的構造函數,而 hexu_lazyinit 對象 是在 Console.WriteLine("剛剛執行到這里!"); ,執行之后才被初始化的。