你真的了解Ioc与AOP吗?(4)

本文介绍如何通过Remoting技术使现有系统具备分布式远程访问能力,包括调整对象类、发布服务及客户端调用流程。

本部分示例代码请参考"src/Step4"目录

五、使用Remoting对原有系统进行改造

如果使用Remoting技术对HelloGenerator进行改造,使其具有分布式远程访问能力,那么在不使用Ioc技术的情况下,我们将会作出如下调整:

(1)让HelloGenerator继承自MarshalByRefObject类

如果要让某个对象具有分布式的功能,必须使其继承自MarshalByRefObject,这样才可以具有远程访问的能力。因此我们需要调整EnHelloGenerator和CnHelloGenerator的代码。这里以EnHelloGenerator为例:

using System;
namespace IocInCSharp
{
   public class EnHelloGenerator : MarshalByRefObject, IHelloGenerator
   {
      public string GetHelloString(string name)
      {
         return String.Format("Hello, {0}", name);
      }
   }
}

(2)将修改后的HelloGenerator发布出去

在这一步中,我们创建了一个新的Console应用程序RemotingServer,并在其中注册了一个Channel,发布服务并进行监听。代码如下:

using System;
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
   public class Server
   {
      public static void Main()
      {
         int port = Convert.ToInt32(ConfigurationSettings.AppSettings["LocalServerPort"]);
         try
         {
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
            BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
            IDictionary props = new Hashtable();
            props["port"] = port;
            props["timeout"] = 2000;
            HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
            ChannelServices.RegisterChannel(channel);
            RemotingConfiguration.RegisterWellKnownServiceType(
               typeof(EnHelloGenerator),
               "HelloGenerator.soap",
               WellKnownObjectMode.Singleton);
            Console.WriteLine("Server started!/r/nPress ENTER key to stop the server...");
            Console.ReadLine();
         }
         catch
         {
            Console.WriteLine("Server Start Error!");
         }
      }
   }
}

(3)全新的客户端调用代码

为了使得客户端MainApp能够调用到远程的对象,我们需要修改它的代码,注册相应的Channel并进行远程访问。修改后的MainApp代码如下:

using System;
using System.Configuration;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;
namespace IocInCSharp
{
   public class MainApp
   {
      public static void Main()
      {
         //建立连接
         BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
         BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
         serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
         IDictionary props = new Hashtable();
         props["port"] = System.Convert.ToInt32(ConfigurationSettings.AppSettings["ClientPort"]);
         HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
         ChannelServices.RegisterChannel(channel );

         //创建远程对象
         ISayHello sayHello = new SayHello();
         string RemoteServerUrl = ConfigurationSettings.AppSettings["RemoteServerUrl"];
         sayHello.HelloGenerator = (IHelloGenerator)Activator.GetObject(typeof(IHelloGenerator), RemoteServerUrl);
         sayHello.SayHelloTo("zhenyulu");
      }
   }
}

在这段代码中,远程对象的创建是通过(IHelloGenerator)Activator.GetObject(typeof(IHelloGenerator), RemoteServerUrl)实现的。到此为止,我们就完成了对原有系统的Remoting改造。

经过调整后的系统,其组件间相互依赖关系如下图所示:

注意ICommon.dll文件在Client和Server端都有。

在整个调整过程中,我们修改了Server端的EnHelloGenerator以及CnHelloGenerator的代码,Client端的MainApp也 作了修改,以加入了远程访问机制。那么能不能对原有代码不作任何修改就实现远程访问机制呢?当然可以!不过我们还要请出Sping.net帮助我们实现这一切。

(待续)

<think>好的,我需要回答用户关于IOCAOP的概念、原理、区别联系的问题。首先,我得回忆一下相关的知识,并结合提供的引用内容来组织答案。 首先,IOC,也就是控制反转,是Spring的核心之一。根据引用[1][4],IOC的主要思想是将对象的创建依赖关系的管理从程序内部转移到第三方容器。这样做的目的是降低耦合度,提高灵活性。用户提到控制反转的具体实现是依赖注入(DI),或者有人认为DI是IoC的一种实现方式。这点需要明确,可能需要指出不同的观点。 接下来是AOP,面向切面编程。引用[2][3]详细说明了AOP的基本概念,比如连接点、切入点、通知等。AOP用于处理横切关注点,如日志、事务等,这些功能分散在多个地方,通过AOP可以模块化处理,避免代码冗余。需要解释AOP的原理,比如动态代理,以及它在Spring中的实现方式,比如JDK动态代理CGLIB,引用[3]提到了这些内容。 然后,关于两者的区别联系。IOC主要负责对象的管理依赖注入,而AOP处理横切关注点。它们的应用场景不同,但都属于Spring的核心机制,共同提升代码的可维护性扩展性。需要指出它们如何协同工作,比如在IOC管理的对象上应用AOP的切面。 在结构上,用户希望答案分点清晰,可能需要分为概念、原理、区别、联系几个部分。每个部分引用相应的引用内容,比如在解释IOC时引用[1][4],AOP引用[2][3]。要注意引用标识的正确添加,比如在提到控制反转时引用[^1][^4],AOP的基本概念引用[^2][^3]。 可能还需要检查是否有遗漏的知识点,比如IOC的其他实现方式,或者AOP的织入过程。确保覆盖用户的问题,包括原理、区别联系,而不仅仅是概念。 最后,生成相关问题,可能需要围绕IOCAOP的应用、具体实现方式、优缺点等方面提问。例如,如何实现依赖注入,或者AOP在实际项目中的使用案例。 现在需要把这些思考整理成一个结构清晰的中文回答,正确使用引用,并确保LaTeX格式符合要求,比如行内公式用$...$,独立公式用$$...$$。不过当前问题可能不需要数学公式,但如果有相关例子可能需要添加。例如,如果讨论AOP的切入点表达式,可能需要使用LaTeX,但根据用户的问题,可能不涉及数学表达式,所以可能不需要。不过要确保其他格式正确,比如代码块使用反引号,引用标识正确放置。 总结一下,回答的结构应该是: 1. 概念 - IOC - AOP 2. 原理 - IOC的实现(DI) - AOP的动态代理 3. 区别 - 关注点不同 - 实现方式不同 4. 联系 - 共同目标 - 协同工作 5. 相关问题 每个部分引用相应的内容,例如在IOC概念部分引用[^1],在AOP原理部分引用[^3]等。确保每个引用标识自然出现在句末,不重复使用同一引用多次,除非必要。 现在开始撰写正式的回答,确保符合所有格式要求,使用中文,分点清晰,引用正确。</think>### 一、IOC(控制反转)AOP(面向切面编程)的概念及原理 #### 1. **IOC(控制反转)** - **概念** **控制反转(IoC)** 是一种设计思想,其核心是将对象的创建依赖关系的控制权从程序代码中转移到外部容器(如Spring框架)。在传统编程中,对象直接通过`new`关键字创建并管理依赖,而IoC通过第三方(容器)统一管理对象生命周期依赖注入(DI)。例如,类A依赖类B时,不再由A主动创建B,而是由容器将B注入到A中[^4]。 - **原理** IoC通过**依赖注入**实现,常见方式包括构造器注入、Setter方法注入接口注入。Spring容器负责读取配置(XML或注解),创建对象并建立依赖关系。这种机制降低了代码耦合度,提升了可维护性扩展性。 #### 2. **AOP(面向切面编程)** - **概念** **面向切面编程(AOP)** 是对面向对象编程(OOP)的补充,用于处理**横切关注点**(如日志、事务、权限等)。这些功能分散在多个模块中,AOP通过动态织入代码的方式将其模块化,避免代码冗余[^2][^3]。 - **原理** AOP基于**动态代理**技术实现,主要步骤如下: 1. **定义切面(Aspect)**:包含通知(Advice)切入点(Pointcut)。 2. **织入(Weaving)**:在目标对象的方法执行前后插入增强逻辑。 3. **代理生成**:Spring通过JDK动态代理(接口)或CGLIB(类)创建代理对象,实现对目标对象的增强。 ### 二、IOCAOP的区别联系 #### 1. **区别** | **维度** | **IOC** | **AOP** | |----------------|----------------------------------|----------------------------------| | **关注点** | 对象创建依赖管理 | 横切关注点的模块化 | | **实现方式** | 依赖注入(DI) | 动态代理、反射 | | **应用场景** | 解耦对象间的直接依赖 | 日志、事务、权限等公共功能 | #### 2. **联系** - **共同目标**:提升代码的可维护性扩展性。IOC通过解耦对象依赖,AOP通过分离横切逻辑,两者协同降低系统复杂度。 - **协同工作**:在Spring中,IOC容器管理的对象是AOP的**目标对象**。AOP通过代理机制增强这些对象的功能,例如事务管理依赖于IOC注入的数据源。 ### 三、示例说明 - **IOC示例**: ```java // 传统方式:由类A主动创建B class A { private B b = new B(); } // IOC方式:由容器注入B @Component class A { @Autowired private B b; } ``` - **AOP示例**(记录方法执行时间): ```java @Aspect public class LogAspect { @Around("execution(* com.example.service.*.*(..))") public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms"); return result; } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值