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框架参考文档