zoukankan      html  css  js  c++  java
  • Spring.NET教程(十八)——整合Remoting(应用篇)

    Spring.Services命名空间的目的是为业务服务提供位置的透明性。我们相信使用普通的接口和.NET类,用户应该可以用最简单的方式实现服务。我们也认为在将某个服务发布给客户端的时,应该只关心服务的配置,而无需关心服务的实现。

    在Spring.Services命名空间的支持下,可以用IoC容器中的服务导出对象将任一个普通对象发布为web服务、企业服务组件或远程对象。这里说的“普通对象”是指不继承或应用基础框架中任何特殊的基类(如MarshalByRefObject)或特性(如WebMethod)的对象。目前Spring.NET要求要发布的对象必须实现一个业务接口(按:即要发布的类必须实现某个接口,但这并非是限制,毕竟面向接口无论在什么时候都是好的编程实践)。Spring.NET的Remoting导出类会自动为其创建一个继承自MarshalByRefObject代理类。在服务端,可以将SAO类型注册为SingleCall或Singleton模式,也可以为每个对象配置生存期和租赁时间。另外,还可以将应用了AOP通知的对象发布为SAO。在客户端,可以用面向接口的最佳编程方式获取CAO的代理对象。Spring.NET还为Remoting创建了专门的schema来简化xml配置,不过我们仍然可以使用标准的schema来创建对象定义。

      传统方式,在服务器需要使用RemotingConfiguration.Configure("xxx.exe.config")的方式启动服务,在客户端需要IContract contract = (IContract) Activator.GetObject ( typeof (IContract ), "tcp://localhost:1800/xxxx")的方式来注册服务。现在,一切都由Spring.NET而随之改变。

      准备条件:  

      [Serializable]

        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }
     
        public interface IPersonContract
        {
            void SavePerson(Person model);
            Person GetPerson();
        }

    PersonContract

        public class PersonContract : IPersonContract
        {
            private Person m_person;
            public void SavePerson(Person model)
            {
                this.m_person = model;
                this.m_person.Name += "冬";
                this.m_person.Age++;
            }
            public Person GetPerson()
            {
                return this.m_person;
            }
        }

      一、部署为Singleton模式:

      服务端

      App.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <sectionGroup name="spring">
          <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
          <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
          <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
        </sectionGroup>
      </configSections>

      <spring>
        <parsers>
          <parser type="Spring.Remoting.Config.RemotingNamespaceParser, Spring.Services" />
        </parsers>
        <context>
          <resource uri="config://spring/objects" />
        </context>
        <objects xmlns="http://www.springframework.net"
                         xmlns:r="http://www.springframework.net/remoting">
          <object id="personContract" type="RemotingServer.PersonContract, RemotingServer"/>
          <!--自动配置服务-->
          <r:configurer filename="RemotingServer.exe.config" />
          <!--目标对象名和服务名-->
          <r:saoExporter targetName="personContract"
                     serviceName="PersonRemotingServer" />
        </objects>
      </spring>
      <system.runtime.remoting>
        <application>
          <channels>
            <channel ref="tcp" port="1800" />
          </channels>
        </application>
      </system.runtime.remoting>
      
    </configuration>

    Program

        class Program
        {
            static void Main(string[] args)
            {
                IApplicationContext ctx = ContextRegistry.GetContext();
                Console.WriteLine("服务器已启动");
                Console.ReadLine(); 
            }
        }

      客户端

      App.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <sectionGroup name="spring">
          <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
          <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
        </sectionGroup>
      </configSections>

      <spring>
        <context>
          <resource uri="config://spring/objects" />
        </context>
        <objects xmlns="http://www.springframework.net">
          <object id="PersonRemotingServer" type="Spring.Remoting.SaoFactoryObject, Spring.Services">
            <property name="ServiceInterface" value="IContract.IPersonContract, IContract" />
            <property name="ServiceUrl" value="tcp://localhost:1800/PersonRemotingServer" />
          </object>
        </objects>
      </spring>
      
    </configuration>

    Program

        class Program
        {
            static void Main(string[] args)
            {
                IApplicationContext ctx = ContextRegistry.GetContext();
                IPersonContract server = (IPersonContract)ctx.GetObject("PersonRemotingServer");
                Person tempPerson = server.GetPerson();
                tempPerson = tempPerson ?? new Person() { Name = "刘冬", Age = 26 };
                server.SavePerson(tempPerson);
                Person person = server.GetPerson();
                string msg = string.Format("姓名:{0},年龄:{1}", person.Name, person.Age);
                Console.WriteLine(msg);
                Console.ReadLine(); 
            }
        }

      运行效果:

    Spring.NET教程(二十)——整合Remoting(应用篇) Level 200

      第一次调用

    Spring.NET教程(二十)——整合Remoting(应用篇) Level 200

      第二次调用

    Spring.NET教程(二十)——整合Remoting(应用篇) Level 200

      二、部署为SingleCall模式:

      修改对象的属性

    <object id="personContract" type="RemotingServer.PersonContract, RemotingServer" singleton="false"/>

      Program

        class Program
        {
            static void Main(string[] args)
            {
                IApplicationContext ctx = ContextRegistry.GetContext();
                IPersonContract server = (IPersonContract)ctx.GetObject("PersonRemotingServer");
                Person tempPerson = server.GetPerson();
                tempPerson = tempPerson ?? new Person() { Name = "刘冬", Age = 26 };
                server.SavePerson(tempPerson);
                Person person = server.GetPerson();
                string msg = person == null ? "对象为空" : string.Format("姓名:{0},年龄:{1}", person.Name, person.Age);
                Console.WriteLine(msg);
                Console.ReadLine(); 
            }
        }

      调用

    Spring.NET教程(二十)——整合Remoting(应用篇) Level 200

  • 相关阅读:
    docker 基于现有镜像修改后保存,上传私有仓库
    新装docker 从本地仓库下载
    decode_json 必须是unicode形式的字符
    浅谈消息队列的原理及优势
    javascript基础修炼(10)——VirtualDOM和基本DFS
    消息队列属性及常见消息队列介绍
    【Angular专题】——【译】Angular中的ForwardRef
    单体应用微服务改造实践
    SpringCloud微服务2-服务提供者和消费者
    基于CSE的微服务工程实践-Native API先行
  • 原文地址:https://www.cnblogs.com/millen/p/1635988.html
Copyright © 2011-2022 走看看