Castle 学习 之 动态代理

作者: 转交遇见陈绮贞 | 来源:发表于2016-04-14 00:16 被阅读346次

前几天看见在项目中用Castle来实现动态代理,觉得很有意思,就找个时间自己研究一下。介绍就免了,那开始吧。

    public class AccountController : Controller
    {
        private AccountService accountService = new AccountService();
        // GET: Account
        public ActionResult Index(string name)
        {
            ViewBag.Msg = accountService.GetUser(name);
            return View();
        }
    }

以前Service的实现基本上是IOC或者单例,今天我们就用动态代理来实现。

        public ActionResult Index(string name)
        {
            var proxy = new ProxyGenerator(); //提供类和接口的代理对象
            var interceptor =new AccountInterceptor();  //拦截器
            //var logInterceptor = new LogInterceptor();
            var accountService = proxy.CreateClassProxy<AccountService>(interceptor);
            ViewBag.Msg = accountService.GetUser(name);
            return View();
        }

ProxyGenerator类会创建一个代理类来继承目标类,并重写目标类中虚方法。

    public class AccountInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            var arguments = invocation.GetArgumentValue(0) as string;

            if (string.IsNullOrWhiteSpace(arguments))
            {
                invocation.ReturnValue = "nono";
                invocation.SetArgumentValue(0, "Stranger");
                invocation.Proceed();
                invocation.ReturnValue = "Stranger";
                return;
            }
            else if (arguments.Equals("陈绮贞"))
            {
                invocation.SetArgumentValue(0,arguments+"SAMA!");
                invocation.Proceed();
                return;
            }
            invocation.Proceed();
            return;
        }
    }

拦截器需要需要实现IInterceptor接口,实现Intercept方法。Intercept接受一个实现了IInvocation接口类的参数,invocation个参数封装了一个代理的方法,其中Proceed用于调用目标方法。看一下方法注释。

        // 摘要:(度娘翻译)
        //     Proceeds the call to the next interceptor in line, and ultimately to the target
        //     method.将调用到下一个拦截线,并最终向目标方法。
        //
        // 备注:
        //     Since interface proxies without a target don't have the target implementation
        //     to proceed to, it is important, that the last interceptor does not call this
        //     method, otherwise a System.NotImplementedException will be thrown.
        没有目标的接口代理没有目标实现要继续进行,这是很重要的,即最后一个拦截不调用这个方法,否则会抛出 system.notimplementedexception。
        void Proceed();

解释一下:ProxyGenerator的CreateClassProxy方法接受的是一个实现了IInterceptor接口的拦截器可变数组,并按顺序执行,类似一个调用链。Proceed被调用时,若果当前拦截器之后还有拦截器等待执行,则将调用传递到下一个拦截器,而不会去调用需要执行的方法,等到最后一个拦截器时才调用目标方法。如果我们调用的方法不是虚方法,也不会抛出异常的。(这里有个疑问:记得我在公司时,当我们调用的方法不是虚函数时也能被拦截到,Proceed方法不调用目标方法,然后拦截器结束后才会调用目标方法,今天debug时却发现拦截器一直没进去,不知道是不是由于使用的CreateClassProxy重载方法不同,明天去公司看一下。更新:虽然调用的方法不是虚函数,但是其内部调用了一个虚函数,这个虚函数被拦截到了,而不是调用的方法被拦截到。)

IInvocation接口里有一些方法可以使我们获取和设置目标方法的参数可返回值,在这里我们就可以做一些参数上的验证和日志的记录。

Castle的动态代理很简单明了,也是AOP实现方式的一种,有兴趣的可以了解一下。

PS:有错误欢迎指摘。

相关文章

  • Castle 学习 之 动态代理

    前几天看见在项目中用Castle来实现动态代理,觉得很有意思,就找个时间自己研究一下。介绍就免了,那开始吧。 以前...

  • Castle 学习 之 动态代理(2)

    接着上次的学习。 假如我们的代理类有三个需要拦截的方法,其中一个不需要被拦截(在某种情况下,但是在其他时候需要被拦...

  • Castle 学习 之 动态代理(3)

    简单了学习一下其他几种代理方式。其实是懒癌 先插入一个小tips:ProxyGenerationOptions,I...

  • Java 动态代理

    java的动态代理机制详解 JDK动态代理详解 Java核心技术点之动态代理

  • 设计模式~代理模式

    学习代理模式内容: ★ 静态代理、 ★ 动态代理(JDK动态代理、CGLIB动态代理)、 ★ 拦截器的原理和日志记...

  • Spring学习之动态代理

    Spring学习之动态代理 前言 动态代理,是一种通过运行时操作字节码,以达到增强类的功能的技术,也是Spring...

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 动态代理解析

    动态代理解析 问题 学习动态代理对我们有什么用? 动态代理是什么? 有什么作用?适用场景在哪里? 学习作用:了解r...

  • Java代理模式之JDK动态代理

    了解什么是动态代理模式,可参考Java设计模式之代理模式 简介 JDK动态代理是java.lang.reflect...

  • 面试系列~动态代理实现与原理

    动态代理有JDK动态代理, CGLIB动态代理, SpringAOP动态代理 一,JDK动态代理  jdk动态代理...

网友评论

    本文标题:Castle 学习 之 动态代理

    本文链接:https://www.haomeiwen.com/subject/tkkglttx.html