1. 程式人生 > >Spring.NET教程(五)容器中物件的作用域(基礎篇)

Spring.NET教程(五)容器中物件的作用域(基礎篇)

容器中物件的部署分為兩種方式:singleton和非singleton(Java裡叫prototype)。這裡的singleton指的是“單例模式”,就是說當一個物件被定義為singleton時,容器中就只會有一個共享的例項,任何時候通過id或別名請求該物件都會返回這個共享例項的引用(也就是說這個物件只會被建立一次)。當使用非singleton,或者說原型模式佈署時,每次請求物件都會建立新的例項。在某些場合,如果需要為每個使用者返回單獨的使用者物件或其它物件,非singlton佈署模式就比較理想。Spring.net預設為singleton模式。每次呼叫GetObject方法時得到的都是同樣的例項;當singleton="false"時,每次呼叫GetObject方法時得到的則是不同的例項。

<!--單例模式-->

<object id="personDao" type="SpringNetScop.PersonDao, SpringNetScop" />

CreateWithSingleton

[Test]

public void CreateWithSingleton()

{

string[] XMLFiles = new string[] 

{

"assembly://SpringNetScop/SpringNetScop/Objects.XML"

};

IApplicationContext context = new XmlApplicationContext(xmlFiles);

IObjectFactory factory = (IObjectFactory)context;

object obj1 = factory.GetObject("personDao");

object obj2 = factory.GetObject("personDao");

Assert.AreEqual(obj1, obj2);

}

我們用NUnit可以看到下圖:

 

 使用singleton="false"的程式碼

<!--非單例模式-->

<object id="person" type="SpringNetScop.Person, SpringNetScop" singleton="false" />

CreateWithOutSingleton

[Test]

public void CreateWithOutSingleton()

{

string[] XMLFiles = new string[] 

{

"assembly://SpringNetScop/SpringNetScop/Objects.XML"

};

IApplicationContext context = new XmlApplicationContext(xmlFiles);

IObjectFactory factory = (IObjectFactory)context;

object obj1 = factory.GetObject("person");

object obj2 = factory.GetObject("person");

Assert.AreNotEqual(obj1, obj2);

}

Person

public class Person

{

public Person()

{

Console.WriteLine("Person被例項");

}

public override string ToString()

{

return "我是Person";

}

~Person()

{

Console.WriteLine("Person被銷燬");

圖為:

 

這說明singleton=false後,每次呼叫GetObject方法獲取的物件是不同例項的,當脫離呼叫方法(CreateWithOutSingleton)的作用域後,該例項會被Spring.net容器銷燬。

lazy-init屬性是指:當Spring.NET容器初始化的時候標註該屬性的物件將被例項化,反之則是呼叫GetObject方法的時候才被例項化。

<!--呼叫時載入-->

<object id="personServer" type="SpringNetScop.PersonServer, SpringNetScop" lazy-init="true" />

CreateWithLazy

[Test]

public void CreateWithLazy()

{

string[] XMLFiles = new string[] 

{

"assembly://SpringNetScop/SpringNetScop/Objects.XML"

};

IApplicationContext context = new XmlApplicationContext(xmlFiles);

IObjectFactory factory = (IObjectFactory)context;

object dao = factory.GetObject("personDao");

Console.WriteLine(dao.ToString());

object server = factory.GetObject("personServer");

Console.WriteLine(server.ToString());

}

PersonServer

public class PersonServer

{

public PersonServer()

{

Console.WriteLine("PersonServer被例項");

}

public override string ToString()

{

return "我是PersonServer";

}

}

如圖:

 

PersonDao類未設定lazy-init屬性,則當Spring.NET初始化時被例項;PersonServer類設定lazy-init="true",則當呼叫GetObject方法時才被例項。

一般情況下可以有選擇的設定lazy-init屬性,正如雙刃劍一樣,設定為lazy-init=true的時候應用程式啟動時會快一點,但是在啟動的時候就不能夠幫我們檢測錯誤,但當呼叫的時候一旦發生錯誤,後果是不堪設想的。

更多資料請檢視Spring.NET中文手冊。