• Spring通过容器获取配置对象及事件注入(学习笔记二)


      使用Spring的基础是配置配置文件。只要深入理解它的配置规则,能极大方便我们的开发。

      Spring使用的基础是通过IObjectFactory、IApplicationContext等等容器来获取我们在配置文件中配置的依赖对象。上一节中讲述了最基本的使用配置文件获取对象的三种方式。这一节打算更深入一些说说获取对象的方式。

      本节要点:

      一、Spring的配置及通过相应的配置获取对象。

      二、Spring对事件的注入

    首先介绍软件环境:

      Spring的版本为:Spring1.3。开发工具为:VS2008 Sp1。

           一、Spring的配置以及通过相应的配置获取对象。

          1、通 过静态工厂方法创建对象。将对象的type设置为包含静态方法的类型,另外还需设置factory-method的值为静态方法名。Spring会通过我们设置的静态方法名来获取对象。配置如下:

    代码
    1 <object id="exampleObjectFactory" type="SpringLesson1.ExampleObjectFactory,SpringLesson1"
     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对象。代码如下:

    代码
    1     IApplicationContext context = ContextRegistry.GetContext(); 
    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属性在配置文件中的可以不用指出。

    配置如下:

    代码
    1 <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
    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>

    创建对象的方式如下:

    代码
    1 IApplicationContext context = ContextRegistry.GetContext();
    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、泛型对象的创建。泛型类在配置文件中应指明类型。另外中中带有泛型参数的属性中,也应该指明其类型。

    配置如下:

    代码
    1 <object id="genenicObj" type="GenericsCreate.GenenicObject&lt;string>,GenericsCreate">
    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>

    获取方式与上面相同:

    代码
    1 using (IApplicationContext context = ContextRegistry.GetContext())
    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的配置如下:

    代码
    1 <object id="emailObject" type="SpringEvent.EmailObject,SpringEvent">
    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>

    事件发布者代码如下:

      

    代码
    1 publicdelegatevoid EmailCallBack(string eventSource,Email email);
    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 }

    事件订阅者代码如下:

      

    代码
    1 public SubcriberClient()
    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的代码:

     代码

    具体时间实现代码如下:

      

    代码
    1using (IApplicationContext context = ContextRegistry.GetContext())
    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中还有一种更简单的方式处理事件。

    配置如下:

    代码
    1<object id="subEvent" type="SpringEvent2.SubscriberEvent,SpringEvent2">
    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的值所发布的事件

     事件发布者代码如下:

     代码

    事件订阅者代码如下:

      

    代码
    1 publicclass SubscriberEvent
    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

    代码实现为:

     代码

    1using(IApplicationContext context=ContextRegistry.GetContext())
    2 {
    3 PublishEvent pubEvent = (PublishEvent)context.GetObject("pubEvent");
    4 pubEvent.PublisMyhEvent();
    5 Console.ReadLine();
    6
    7
    8 }


    代码下载:Spring的配置以及事件注入

    参考文档:Spring.Net框架参考文档

  • 相关阅读:
    第一个Android应用 扫描宝 欲挑战传统扫描枪
    前端工程师在实现支付功能的时候能做些什么(V客学院技术分享)?
    HBuilder android 打包指南(V客学院技术分享)
    JavaScript 事件处理详解
    关于webpack的path和publicPath。
    svg线条的动画到渐变
    vue目录结构及其对应作用
    数据改变视图未变问题解决(Object.assign)
    ES6语法的简单介绍——拓展运算符
    webpack打包原理
  • 原文地址:https://www.cnblogs.com/tyb1222/p/1890713.html
Copyright © 2020-2023  润新知