第四章 Spring.Net 如何管理您的类___对象的手动装配

前面我们知道了什么是对象,什么是对象工厂,什么是应用程序上下文。这一次我们来看一下对象的装配。

  Spring.Net 中有多种装配对象的方式,装配这个词可能比较学术化,我们可以理解为对象的创建。

  Spring.Net 中常用的装配方式有 手动装配和自动装配。手动装配就是根据配置文件然后装配对象,而自动装配是指Spring.Net根据指定的自动模式查找相关属性并自动装配。这两种装配方式之下又分为 通过属性进行装配,通过构造器进行装配,通过静态工厂装配,通过实例工厂装配,泛型的装配等等。这些装配方式在下面会一一介绍。

4.4.1  手动装配

  在Spring.Net 中,手动装配 分为 多种装配方式,我们在下面介绍常用的几种装配方式:

  (1) 通过属性进行装配

  (2) 通过构造器进行装配

  (3) 通过静态工厂装配

  (4) 通过实例工厂装配

  (5) 对数组的装配

  (6) 对泛型集合的(List,Dictionary)装配

  (7) 泛型对象的装配

  (8) 事件的装配

4.4.1.1  通过属性进行装配

  在本小节,我们通过举例来说明,如何通过属性来装配对象,我们这里只讨论简单的属性,比如数组,集合,自定义类,这些属性我们放在后面一起讨论,这里还是举常用的Person与Dog的故事。

  一个Person类,拥有Id,Name,IsStudent,Dog(小狗)等属性,睡醒的方法(SleepLightly),还有一个ToString()的方法来输出信息

 1 using System;
 2 using System.Collections.Generic;
 3
 4 namespace CnblogLesson_4_4_1.Model
 5 {
 6     /// <summary>
 7     /// 人类
 8     /// </summary>
 9     public class Person
10     {
11         public Person() { }
12         public Person(string name) {
13             this.Name = name;
14         }
15         public Person(int id, string name, bool isStudent,Dog dog) {
16             this.Id = id;
17             this.Name = name;
18             this.IsStudent = isStudent;
19             this.Dog = dog;
20         }
21
22         /// <summary>
23         /// 编号
24         /// </summary>
25         public int Id { get; set; }
26
27         /// <summary>
28         /// 人的名称
29         /// </summary>
30         public string Name { get; set; }
31
32         /// <summary>
33         /// 是否是学生
34         /// </summary>
35         public bool IsStudent { get; set; }
36
37         /// <summary>
38         /// 小狗狗
39         /// </summary>
40         public Dog Dog { get; set; }
41
42         /// <summary>
43         /// 人拥有的物品
44         /// </summary>
45         public Object[] ObjArray { get; set; }
46
47         /// <summary>
48         /// 想要看的书
49         /// </summary>
50         public List<string> Books;
51
52         /// <summary>
53         ///  朋友们
54         /// </summary>
55         public Dictionary<string, string> Friends { get; set; }
56
57         /// <summary>
58         /// 睡醒了
59         /// </summary>
60         /// <param name="args"></param>
61         public void SleepLightly(string args)
62         {
63             Console.WriteLine("{0}叫了,把主人惊醒了", args);
64         }
65
66         /// <summary>
67         /// 重写ToString方法
68         /// </summary>
69         /// <returns></returns>
70         public override string ToString()
71         {
72             if (Dog == null)
73             {
74                 Console.WriteLine("我是{0},我的Id是:{1},我是不是学生:{2},我没有小狗狗", Name, Id, IsStudent);
75             }
76             else {
77                 Console.WriteLine("我是{0},我的Id是:{1},我是不是学生:{2},我的小狗叫:{3}", Name, Id, IsStudent, Dog.Name);
78             }
79             return String.Empty;
80         }
81     }
82 }

  小狗拥有一个Name的属性,一个事件,还有一个叫的方法:

 1 namespace CnblogLesson_4_4_1.Model
 2 {
 3     /// <summary>
 4     /// 小狗狗
 5     /// </summary>
 6     public class Dog
 7     {
 8         public Dog() { }
 9         public Dog(string name) {
10             this.Name = name;
11         }
12
13         /// <summary>
14         /// 小狗狗的名字
15         /// </summary>
16         public string Name { get; set; }
17
18         public event SleepLightly sleepLightly;
19
20         /// <summary>
21         /// 叫
22         /// </summary>
23         public void Cry()
24         {
25             if (sleepLightly != null)
26             {
27                 sleepLightly.Invoke("猫");
28             }
29         }
30     }
31 }

  程序主方法:

 1 using System;
 2 using Spring.Context;
 3 using Spring.Context.Support;
 4
 5 namespace CnblogLesson_4_4_1
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             //通过IApplicationContext来配置
12             IApplicationContext context = ContextRegistry.GetContext();
13                //4.4.1.1 通过属性进行装配
14             Person hexu = (Person)context.GetObject("hexu");
15             hexu.ToString();
16
17             Console.ReadKey();
18         }
19     }
20 }

  我们接下来创建一个Object.xml 来配置对象,将Object.xml设置为嵌入式资源,(这里一定要设置为潜入式资源)。

  属性的装配一般使用  <property name="Id" value="1" />  标签来表示,name表示要设置的属性名,如设置Id,value表示Id属性的值。

  装配简单的属性:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3
 4   <!--4.4.1.1 通过属性进行装配-->
 5
 6   <!--人类对象-->
 7   <object id="hexu" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
 8     <!--设置编号-->
 9     <property name="Id" value="1"/>
10     <!--设置姓名-->
11     <property name="Name" value="hexu"/>
12     <!--设置是否是学生-->
13     <property name="IsStudent" value="false"/>
14
15     <!--我的宠物为一个对象,这个对象的引用是id为kaqi的狗狗-->
16     <property name="Dog" ref="kaqi"/>
17   </object>
18
19   <!--宠物对象-->
20   <object id="kaqi" type="CnblogLesson_4_4_1.Model.Dog,CnblogLesson_4_4_1">
21     <property name="Name" value="卡琪"/>
22   </object>
23 </objects>

  装配自定义对象:

  标签 <property name="Dog" ref="kaqi"/> 的属性ref可以设置这个属性为一个引用,这个引用为id为kaqi的object标签。

  通过监视变量,我们可以看到,我们已经将属性装配成功。

4.4.1.2  通过构造器进行装配

  在上一小节我们讨论了如何通过属性来装配对象,这一小节我们讨论如何通过构造器装配。这一次,我们对Person类和 Dog 类分别增加了有参数构造函数。

  通过构造函数装配,需要使用到<constructor-arg name="Name" value="hexu"/>标签。Name表示构造函数参数名称,value表示该参数所赋的值。

  Objects.xml为下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3   <!--4.4.1.2 通过构造器进行装配-->
 4
 5   <!--有一个参数的构造函数-->
 6   <object id="hexu_2_1" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
 7     <constructor-arg name="Name" value="hexu"/>
 8   </object>
 9
10   <!--有多个参数的构造函数-->
11   <object id="hexu_2_2" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
12     <constructor-arg name="Id" value="1"/>
13     <constructor-arg name="Name" value="hexu"/>
14     <constructor-arg name="IsStudent" value="true"/>
15     <constructor-arg name="Dog" ref="kaqi_2"/>
16   </object>
17
18   <!--宠物对象_2-->
19   <object id="kaqi_2" type="CnblogLesson_4_4_1.Model.Dog,CnblogLesson_4_4_1">
20     <property name="Name" value="卡琪"/>
21   </object>
22 </objects>

  通过运行时监视变量可以看到,通过构造函数装载对象已经成功:

4.4.1.3  通过静态工厂进行装配

通过静态工厂来进行装配,就必须要有工厂对象,我们先来创建一个静态工厂对象

 1 using CnblogLesson_4_4_1.Model;
 2 namespace CnblogLesson_4_4_1.Factory
 3 {
 4     public static class StaticFactory
 5     {
 6         public static Person CreateInstance() {
 7             Dog dog = new Dog("卡琪");
 8             Person person = new Person(1,"hexu",false,dog);
 9             return person;
10         }
11     }
12 }

  再来看一下Objects.xml:

1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3   <!--4.4.1.3 通过静态工厂进行装配-->
4   <object name="staticFactory" type="CnblogLesson_4_4_1.Factory.StaticFactory,CnblogLesson_4_4_1" factory-method="CreateInstance"/>
5 </objects>

  使用静态工厂装配,需要配置一个工厂对象,并且设置静态工厂创建对象的方法factory-method为类中创建对象的方法。

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.4  通过实例工厂进行装配

  通过实例工厂方法装载对象与通过静态工厂方法装载对象的配置方式类似。此时,实例工厂方法所在的对象必须也要配置在同一容器(或父容器)中。

  如果要通过实例工厂方法装载对象,对象定义就不能包含type属性,而要用factory-object属性引用工厂方法所在的对象。注意,该属性值必须是包含工厂方法的对象的名称,且该对象必须定义在当前容器或父容器中。工厂方法的方法名则通过factory-method属性指定。(至于为什么不用type,而要使用factory-object呢?这是Spring.Net他们定义的规则。)这里我们也像通过静态工厂进行装配一样,通过实例工厂装配,需要定义一个实例工厂对象。

  实例工厂类:

 1 using CnblogLesson_4_4_1.Model;
 2 namespace CnblogLesson_4_4_1.Factory
 3 {
 4     public class InstanceFactory
 5     {
 6         public Person CreateInstance() {
 7             Dog dog = new Dog("卡琪");
 8             Person person = new Person(1,"hexu",false,dog);
 9             return person;
10         }
11     }
12 }

  Objects.xml 配置如下:

  使用实例工厂装配,需要配置一个工厂对象。如:Id=”instanceFactory”

  然后还需要一个实例对象id=” instancePerson”,并设置该实例是通过工厂对象创建,设置factory-object="instanceFactory",还要设置工厂创建实例的方法factory-method="CreateInstance"。

  再来看一下Objects.xml:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3
 4   <!--4.4.1.4 通过实例工厂进行装配-->
 5
 6   <!--工厂-->
 7   <object id="instanceFactory" type="CnblogLesson_4_4_1.Factory.InstanceFactory, CnblogLesson_4_4_1" />
 8   <!--创建的对象,factory-object所指向的是instanceFactory,表示通过instanceFactory工厂的CreateInstance方法来创建此对象-->
 9   <object id="instancePerson" factory-method="CreateInstance" factory-object="instanceFactory" />
10
11 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.5  对数组的装配

  前面我们一起讨论过属性的装配,但是前面我们讨论的都是一些简单的属性。这一节我们一起来讨论数组如何装配。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3   <!--4.4.1.5 对数组的装配-->
 4   <!--人类对象-->
 5   <object id="hexu_2_5" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
 6     <!--设置姓名-->
 7     <property name="Name" value="hexu"/>
 8     <property name="ObjArray">
 9       <set>
10         <value>亲人</value>
11         <value>朋友</value>
12         <value>工作</value>
13         <value>程序</value>
14       </set>
15     </property>
16   </object>
17 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.6  对泛型的装配之List

  这一小节,我们一起来讨论对List集合的装载。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3
 4   <!--4.4.1.6 对泛型的装配之List集合-->
 5   <!--人类对象-->
 6   <object id="hexu_2_6" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
 7     <!--设置姓名-->
 8     <property name="Name" value="hexu"/>
 9     <property name="Books">
10       <!--设置集合的类型-->
11       <list element-type="string">
12         <value>重构</value>
13         <value>WCF全面解析</value>
14         <value>设计模式:可复用面向对象软件的基础</value>
15       </list>
16     </property>
17   </object>
18
19 </objects>

  标签<list element-type="string">....</list>表示C#中的List<string>,value 表示 元素的值

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.7  对泛型的装配之Dictionary集合

  这一小节,我们一起来讨论对Dictionary集合的装载。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3
 4   <!--4.4.1.7 对泛型的装配之Dictionary集合-->
 5
 6   <!--人类对象-->
 7   <object id="hexu_2_7" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
 8     <!--设置姓名-->
 9     <property name="Name" value="hexu"/>
10     <property name="Friends">
11       <!--设置集合的类型-->
12       <dictionary key-type="string" value-type="string">
13         <entry key="ZG" value="张哥"/>
14         <entry key="LG" value="李哥"/>
15         <entry key="WG" value="王哥"/>
16       </dictionary>
17     </property>
18   </object>
19
20 </objects>

  标签<dictionary key-type="string" value-type="string">....</dictionary>表示C#中的Dictionary<string,string>,key-type 表示 键的类型,value-type 表示 值的类型。entry则表示每个元素。  

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.8  泛型对象的装配

  Spring.Net 中对泛型对象的创建方法和普通对象是一样的。但有一个很细微的差别。

  在为泛型类对象指定type属性的时候要注意:

  第一,   左尖括号<要替换成字符串“&lt;”,因为在XML中左尖括号会被认为是小于号。可读性来讲,我们都知道这并不是理想的方式。

  第二,type参数值中不能包含程序集的名称,因为程序集名称要求和类型全名用逗号隔开,而在这里逗号已经被用来分隔泛型类的类型参数了。将来可能会用其它字符代替这两个符号,但目前还没找到更具可读性的方案。若要提高可读性,建议使用类型别名。

  先来看一下GenericClass.cs的定义:

1 namespace CnblogLesson_4_4_1.Generic
2 {
3     public class GenericClass<T>
4     {
5         public T obj { get; set; }
6     }
7 }

  Objects.xml 配置如下:

1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4   <!-- 4.4.1.8 泛型类的装配 如: GenericClass<string> -->
5   <object id="hexu_2_8" type="CnblogLesson_4_4_1.Generic.GenericClass&lt;string>, CnblogLesson_4_4_1" >
6     <property name="obj" value="generic"/>
7   </object>
8
9 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

5.4.1.9  事件的装配

  Spring.NET的IoC框架中,还提供事件的注入。通过事件的注入,可以使架构体系的耦合降到最低。仍然使用一个例子:主人正在睡觉,小偷来了,然后小狗发现小偷就汪汪叫,主人被小狗的叫声惊醒。

  创建一个 惊醒的委托:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace CnblogLesson_4_4_1.Model
7 {
8     public delegate void SleepLightly(string args);
9 }

  配置Objects.xml 文件:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3   <!--4.4.1.9事件注入-->
 4
 5   <!--先装载小狗对象-->
 6   <object id="observer_dog" type="CnblogLesson_4_4_1.Model.Dog, CnblogLesson_4_4_1" />
 7   <!--装载主人对象,主人需要监听小狗对  惊醒事件的触发,当小狗叫,主人调用睡醒的方法-->
 8   <object id="observer_person" type="CnblogLesson_4_4_1.Model.Person, CnblogLesson_4_4_1">
 9     <!--使用到listener监听器,ref表示主人要监听的小狗,event表示主人监听小狗的哪个事件,method表示,当监听到的事件触发时,调用自己的睡醒事件-->
10     <listener event="sleepLightly" method="SleepLightly">
11       <ref object="observer_dog"/>
12     </listener>
13   </object>
14
15 </objects>

  装配事件需要使用到<listener event="sleepLightly" method="SleepLightly">...</listener>标签,由于在Dog.cs 和 Person.cs 中都已经写好了 代码,现在只需要通过Objects.xml来动态设置参数。<listener event="sleepLightly" method="SleepLightly">...</listener>标签中,event就是用来指定,需要设置Dog.cs类中的哪个事件(上面是设置sleepLightly事件),method表示,这个事件的值是哪个方法。使用<ref object="observer_dog"/>表示,这个事件的参数。您看,在Dog.cs 类中,我传了一个字符串“猫”作为参数,最后输出结果为“猫叫了,把主人惊醒了”!

  通过运行时监视变量,通过静态工厂装载对象已经成功:

  到目前为止,Spring.Net 中大部分手动装配对象方式 都在上面的文章里了,在下面的一章里,会谈到不常用的自动装配方式。

时间: 2024-10-12 08:43:04

第四章 Spring.Net 如何管理您的类___对象的手动装配的相关文章

第十四章、Linux 账号管理与 ACL 权限配置

1. Linux 的账号与群组 1.1 使用者标识符: UID 与 GID 1.2 使用者账号:/etc/passwd 文件结构, /etc/shadow 文件结构 1.3 关于群组: /etc/group 文件结构, 有效与初始群组, groups, newgrp, /etc/gshadow2. 账号管理 2.1 新增与移除使用者: useradd, useradd 参考档, passwd, chage, usermod, userdel 2.2 用户功能:finger, chfn, chsh

《Spring技术内幕》笔记-第四章 Spring MVC与web环境

?上下文在web容器中的启动 1,IoC容器的启动过程 IoC的启动过程就是建立上下文的过程,该上下文是与ServletContext相伴.在Spring中存在一个核心控制分发器,DispatcherServlet,这是Spring的核心.在web容器启动Spring应用程序时,首先建立根上下文,然后ContextLoader建立WebApplicationContext. Web容器中启动Spring过程如下: 在web.xml中,已经配置了ContextLoadListener,该类实现了S

四、spring boot 日志管理

spring boot日志默认采用logback进行输出,你可以对logback进行定制化,方法如下: 在resources文件夹下建立logback.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- base.xml in the spring-boot jar, --> <include resource="org/sprin

【PMP】Head First PMP 学习笔记 第四章

第四章 项目整合管理 项目经理每天的工作 力保项目顺利进行 紧密监督以确保计划进行 计划本身不完善需要予以修正 即使是更大的项目的子项目,也要有收尾的过程 6个整合管理过程 整合管理划分为6个过程,项目经理必须掌握的核心职责. 1.制订项目章程 授权你展开工作的文档,通常由赞助人(为项目提供资金的人)交给你. 2.制订项目管理计划 项目管理计划涵盖了所有知识领域,很大一部分就是告诉你在出现问题时如何处理变更. 3.指导和管理项目执行 确保所有人都在做他们本该做的事,项目创建的产品和项目确实满足干

Mybatis整合Spring实现事务管理的源码分析

一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是看的过程中灵感的显现很重要(就是直觉知道接下来的步骤是什么应该是什么之类的,但是这个自觉是猜的而非蒙的,即过程里是有往会递推看到了一些关键点的而不是抛色子来确定是哪个子类) ,因此自己写的时候也无法将看的过程里产生的想法写得很细,过程也有点跳,如果大家有疑问最好自己去验证(方式就是搜索然后看哪里调用

《互联网+医疗:重构医疗生态》,第四章介绍美国的医药福利管理制度与企业,值得看看,其他章节一般。总体二星。

各章相对独立,是不同的作者. 第四章介绍美国的医疗福利管理的制度与公司,值得看一看.这一章我给三星.其他章节二星,信息以互联网上能查到的信息为主. 以下是书中一些相对有用的信息的摘抄: 1:但是,“互联网+医疗”企业有一个最大的痛点,就是害怕触碰法律“红线”.目前,所有相关企业都宣称“咨询”或“轻问诊”,绝不说是“看病”,更不敢开处方.#314 2:患者的隐私安全在整个在线问诊的服务流程中也是非常重要的.#372 3:相比美国的私人医生模式,中国的私人医生主要还是停留在为居民提供个性化医疗健康管

深入浅出Zabbix 3.0 -- 第四章 主机、用户和权限管理

第四章  主机.用户和权限管理 Zabbix中主机作为一个管理单元,用来管理和组织监控项,它可以包含任意数量和类型的监控项,并且每个主机必须属于至少一个主机组.当主机中的监控项获取监控数据后,Zabbix中创建的用户就可以访问这些数据,同样这些用户必须属于至少一个用户组.你可能注意到不管是主机还是用户,在Zabbix中必须属于至少一个主机组或用户组.为什么要这么做呢?这是因为Zabbix中是通过用户组和主机组来实现用户对主机中监控数据进行访问权限的分配和管理. 4.1主机 4.1.1创建主机 Z

第四章:用户和组管理

第四章:用户和组管理 1.基本概念 1.1.UID&GID Linux是通过UID和GID号来识别用户和组.对某个文件或程序的访问也是以UID和GID为基础.一个执行中的程序继承了调用它的用户的权利和访问权限. 1.2.Linux用户类型 根用户(0):UID为0的用户,能够访问系统任何文件和程序,而不论root根用户是否有权限.root用户通常称为"超级用户" 系统/服务用户(1-999):UID为1-999.系统保留账号,或者某些服务才能使用的的账号 普通用户(大于1000

Testlink1.9.17使用方法( 第四章 测试需求管理 )

第四章 测试需求管理 QQ交流群:585499566 需求规格说明书是我们开展测试的依据.首先,我们可以对项目(产品)的需求规格说明书进行分解和整理,将其拆分为多个需求,一个项目可以包含多个需求,一个需求可以包含多个测试需求. 创建产品需求规格 创建测试需求 一. 创建产品需求规格 单击主页上面的"产品需求"区域->点击[产品需求规格]按钮-->点击[新建产品需求规格] 对"产品需求规格"的描述比较简单,内容包含文档ID.标题.范围,类型.如下图所示: