Spring通過容器獲取配置對象及事件注入(學習筆記二)
使用Spring的基礎是配置配置文件。只要深入理解它的配置規則,能極大方便我們的開發。
Spring使用的基礎是通過IObjectFactory、IApplicationContext等等容器來獲取我們在配置文件中配置的依賴對象。上一節中講述了最基本的使用配置文件獲取對象的三種方式。這一節打算更深入一些說說獲取對象的方式。
本節要點:
一、Spring的配置及通過相應的配置獲取對象。
二、Spring對事件的注入。
首先介紹軟件環境:
Spring的版本為:Spring1.3。開發工具為:VS2008 Sp1。
一、Spring的配置以及通過相應的配置獲取對象。
1、通 過靜態工廠方法創建對象。將對象的type設置為包含靜態方法的類型,另外還需設置factory-method的值為靜態方法名。Spring會通過我們設置的靜態方法名來獲取對象。配置如下:
代碼
factory-method="StaticCreateInstance">
2 </object>
3
4 <object id="target" type="SpringLesson1.ExampleNew,SpringLesson1"/>
5 <object id ="example" type="SpringLesson1.Example,SpringLesson1">
6 <property name="Name" value="test string"></property>
7 </object>
這樣通過容易來獲取Example對象。代碼如下:
代碼
8 Example example = (Example)context.GetObject("exampleObjectFactory");
9 if (example.Name.Length ==0)
10 {
11 Console.WriteLine("the property name of Example length is 0");
12 }
13 else
14 {
15 Console.WriteLine("the property name of Example length is :{0}", example.Name.Length);
16 }
17
18 ExampleNew exampleNew = (ExampleNew)example.CreateNew();
19 Console.WriteLine("the property name of ExampleNew length is {0}",exampleNew.Name);
20
21 Console.ReadLine();
輸出如下:

通過之前的介紹我們知道:通過ID獲取的對象一般應該是type所指定的類型,而在這里使用了靜態方法后獲取到的對象卻發生了變化。
靜態獲取對象小結:
1、靜態方法所在類型通過容器獲取時,獲取的不是Type所指的類型,而是靜態方法所創建的類型。
2、由靜態方法所獲取的對象,直接由代碼執行,不會受配置文件的影響(以上配置中使用value="test string"
但是最后程序輸出的Name屬性長度僅僅為4)。
注意:factory-method所指定的方法名必須為static,否則會有如下異常:

2、通過實例工廠方法創建對象。實例工廠方法所在的對象必須也要配置在同一容器(或父容器)中。如果使用實例工廠方法創建對象,則對象的factory-method的值為創建對象的工廠中創建對象的方法,factory-object的值為創建對象的工廠此時,創建對象的type屬性在配置文件中的可以不用指出。
配置如下:
代碼
2 <object id="exampleObject" type="FactroyIOC.ExampleObject,FactroyIOC"
factory-object="exampleFactory" factory-method="CreateInstance"></object>
3 <object id ="exampleFactory" type="FactroyIOC.ExampleFactory,FactroyIOC"></object>
4
5 </objects>
創建對象的方式如下:
代碼
2
3 ExampleObject example = (ExampleObject)context.GetObject("exampleObject");
4 if (example !=null)
5 {
6 Console.WriteLine("ExampleObject instance is not null");
7 Console.WriteLine("the properties of Example is :{0}", example.Name);
8 }
9 else
10 {
11 Console.WriteLine("ExampleObject instance is null");
12 }
13 Console.ReadLine();
輸出如下:

注意:上述配置文件中factory-method設置的方法名應該為非靜態的,并且應該為public 。如果為靜態則有如下異常:

3、泛型對象的創建。泛型類在配置文件中應指明類型。另外中中帶有泛型參數的屬性中,也應該指明其類型。
配置如下:
代碼
2 <property name="Name" value="test string"></property>
3 <property name="ValueLst">
4 <list element-type="string">
5 <value>genenic aa</value>
6 <value>genenic bb</value>
7 </list>
8 </property>
9
10 <property name="TestList">
11 <list>
12 <value>not genenic aa</value>
13 <value>not genenic bb</value>
14 </list>
15 </property>
16 </object>
獲取方式與上面相同:
代碼
2 {
3 GenenicObject<string> obj = (GenenicObject<string>)context.GetObject("genenicObj");
4 if (obj !=null)
5 {
6 Console.WriteLine(obj.Name);
7 for (int i =0; i < obj.ValueLst.Count; i++)
8 {
9 Console.WriteLine(obj.ValueLst[i]);
10 }
11
12 for (int i =0; i < obj.TestList.Count; i++)
13 {
14 Console.WriteLine(obj.TestList[i]);
15 }
16
17 }
18 else
19 {
20 Console.WriteLine("obj is null");
21 }
22 Console.ReadLine();
23 }
輸出如下圖:

這里我們看到:屬性ValueLst與TestList的配置有點差異。在ValueLst 中必須指明類型,否則程序會拋異常。如下圖:

從異常中我們可以看出如果泛型屬性不指明類型,則它認為屬性是ArrayList類型的。
2、Spring對事件的注入.Spring.NET允許開發人員用松耦合的事件裝配機制來處理事件。通過解耦事件的發布者和訂閱者,大部分事件裝配工作都可由IoC容器處理。事件的發布者可以向事件注冊中心發布它們的所有事件,或者以事件委托的類型、名稱及返回值為過濾依據發布部分事件。事件的訂閱者可以訂閱任意數量的已發布事件.
IApplicationContext通過PublishEvents(object sourceObject)發布sourceObject的所有事件,供適當的訂閱者訂閱;通過Subscribe(object subscriber, Type targetSourceType):subscriber向事件中心訂閱它能夠處理的、由某個特定類型的源對象發布的所有事件。
Spring的配置如下:
代碼
2
3 <property name="BlackList">
4 <list>
5 <value>12@163.com</value>
6 <value>tyb@163.com</value>
7 </list>
8 </property>
9 <property name="EventSource" value="EmailObject"></property>
10 <property name="E_Mail"ref="email"/>
11 </object>
12
13 <object id="email" type="SpringEvent.Email,SpringEvent">
14 <property name="Address" value="12@163.com"></property>
15 <property name="Text" value="this is a Email"></property>
16 </object>
17 <object id="Client" type="SpringEvent.SubcriberClient,SpringEvent" singleton="false"></object>
事件發布者代碼如下:
代碼
2
3 class EmailObject : IApplicationContextAware
4 {
5 public IList BlackList { get; set; }
6
7 publicevent EmailCallBack EmailEvent;
8
9 publicstring EventSource { get; set; }
10
11 public Email E_Mail { get; set; }
12 public IApplicationContext ApplicationContext { privateget; set; }
13
14 publicvoid SendEmail()
15 {
16 if (EmailEvent !=null)
17 {
18 EmailEvent(EventSource, E_Mail);
19 }
20 }
21 }
事件訂閱者代碼如下:
代碼
2 { }
3
4 publicvoid HandleClientEvents(string str, Email email)
5 {
6 Console.WriteLine("value of str is:{0},email address is :{1},email info is {2} ",str,email.Address,email.Text);
7
8 }
9
事件參數Email的代碼:
代碼
具體時間實現代碼如下:
代碼
2 {
3 EmailObject emailObj = (EmailObject)context.GetObject("emailObject");
4 context.PublishEvents(emailObj);
5
6 SubcriberClient client = (SubcriberClient)context.GetObject("Client");
7 context.Subscribe(client, typeof(EmailObject));
8
9 emailObj.SendEmail();
10 Console.ReadLine();
11 }
以上代碼便將client與事件發布者聯系起來。發布者任何時候通過SendEmail觸發事件,都會被client處理。
當然,在Spring中還有一種更簡單的方式處理事件。
配置如下:
代碼
2<listener event="SimpleEvent" method="DoMethod">
3<refobject="pubEvent"/>
4</listener>
5</object>
6
7<object id="pubEvent" type="SpringEvent2.PublishEvent,SpringEvent2"></object>
8
9</objects>
配置文件說明:listener 節點就是配置事件注入的。event的即為事件發布者中的事件名,而method則為事件訂閱者處理的方法,ref值事件訂閱者訂閱的是object的值所發布的事件
事件發布者代碼如下:
代碼
事件訂閱者代碼如下:
代碼
2 {
3 publicvoid DoMethod(object sender, EventArgs e)
4 {
5 if (sender !=null)
6 {
7 Console.WriteLine(sender.ToString());
8 }
9 else
10 {
11 Console.WriteLine("object is null");
12 }
13 }
14
代碼實現為:
代碼
2 {
3 PublishEvent pubEvent = (PublishEvent)context.GetObject("pubEvent");
4 pubEvent.PublisMyhEvent();
5 Console.ReadLine();
6
7
8 }
代碼下載:Spring的配置以及事件注入
參考文檔:Spring.Net框架參考文檔
浙公網安備 33010602011771號