之前做AgentBooking时候,遇到两个问题比较棘手,一个是异常的传递与捕获:如何可以合理地在层层代码调用中统一传递并统一捕获异常。因为如果有一个做法,可以地方统一处理异常,可以使代码减少很多try cath逻辑,也不同时刻关注该怎么抛异常,这样代码写起来就比较happy。
第二个是Log的统一记录。和第一个问题一样,如果可以找到一种方法,可以统一记Log,不用再在代码中时刻关注什么时候该怎么记Log,这肯定是一种更好的改进。
 
        上两个星期去Search了一下AOP(面向切面编程),其思想很大程度上可以给我们提供帮助。AOP大概意思就是说,在代码的编译期或者运行期自动为程序插入额外的功能逻辑。其思想就是将主要业务逻辑和辅助功能分离出来。在MOE中有一个经典的应用场合:每次MOE在调用Web Service时候,都回家RQ序列号并保存到一个txt的Log文件中,所以这个调用webservice的方法既有主要业务逻辑(RQ的生成)的代码,又有RQ入Log的辅助功能。如果应用AOP,则这个方法中只需要写主要业务的逻辑,RQ入LOG的逻辑代码可以交给AOP框架自动在编译期动态(或静态)“插入”到原来的代码里面。
 
    AOP实现手段大概有两种,一是在编译是对代码的IL进行分析,然后插入(官方叫“织入”)额外功能的代码。二是对方法调用进行拦截并执行额外代码逻辑。
    .NET中对方法调用进行拦截主要是通过context对象。参考资料:AOP研究context与拦截
 
    这里主要介绍一下context与方法拦截。(因为IL涉及到编译器,太深奥,不明觉厉,而方法拦截除了AOP,感觉还可以用在其他地方)
 
    在.NET中,每个App Domain(应用程序域,在.net中一个进程可以有N个线程,一个线程可以有N个App Domain)都至少有一个Context,当一个对象被new出来后,就是存在于context中。(我觉得context是更是一种编程思想,就是将资源都放在一个地方。典型的有HttpContext,就集中包含了每个HttpRequest访问时的一些信息)。.net程序第一个context是一个默认context,每个context都有一个ContextID.可以通过Thread.CurrentContext来访问当前Context。
 
    .net里的对象从context的角度可以分为两种:context-aglie object(上下文灵活对象)和context-bound object(上下文绑定对象)。context-aglie object总是存在于这个对象的调用者所在的context中(我查了一下资料,大概是这个意思,但我还没有验证过是不是这样)。对context-aglie object的调用是一种直觉引用,并不是通过代理的调用。这个很重要,因为直接的调用是不能被拦截的,只有通过“代理”的调用才能被拦截,见下文。
    而另一种是context-bound object(上下文绑定对象)。如果一个对象继承了ContextBoundObject ,就成了一个context-bound object。 context-bound object会被强制绑定到一个指定的context中。当一个调用者和被调用的对象处于不同的context中时,这个调用不是直接的引用,而是需要通过代理去进行的。正是因为有这个“代理”,才能在调用过程中做手脚,例如在调用这个对象的一个方法前或调用方法完毕后做一些额外的逻辑(如Log,或者方法执行的时间统计等等),听起来很熟悉?在HttpModule中也是这种做法。
 
 
    这里的“代理”有几种:远程代理(Remote Proxy),虚拟代理(Virtual Proxy),智能引用代理(Smart Reference Proxy).在.NET Remoting中,代理又分为透明代理(Transparent Proxy)和真实代理(Real Proxy)
方法调用的拦截就需要用到透明代理和真实代理。当一个对象调用另一个context里的对象(比如说调用该对象的某个方法),这个调用到达透明代理时会被转换为一个Message,并将Message传给Real Proxy。Real Proxy将Message传到这个对象的过程中,Message会经历由N个MessageSink(消息槽)组成的管道中。每个MessageSink可以对消息进行处理并再次抛给下一个MessageSink,一直将调用传递到那个Object为止。每个MessageSink中便是我们拦截方法调用的地方了。
 
 
提供一个基于Context拦截的Logger 日志组件Demo: AOP Logger

c# AOP编程:Context与方法拦截的更多相关文章

  1. 动态方法拦截(AOP)的N种解决方案

    AOP的本质是方法拦截(将针对目标方法调用劫持下来,进而执行执行的操作),置于方法拦截的实现方案,不外乎两种代码注入类型,即编译时的静态注入和运行时的动态注入,本篇文章列出了几种常用的动态注入方案.这 ...

  2. 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存

    首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...

  3. 使用spring框架进行aop编程实现方法调用前日志输出

    aop编程 之使用spring框架实现方法调用前日志输出 使用spring框架实现AOP编程首先需要搭建spring框架环境: 使用Spring框架实现AOP工程编程之后,不需要我们去写代理工厂了,工 ...

  4. struts2.1笔记03:AOP编程和拦截器概念的简介

    1.AOP编程 AOP编程,也叫面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容.利用A ...

  5. Lind.DDD.LindAspects方法拦截的介绍

    回到目录 什么是LindAspects 之前写了关于Aspects的文章<Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP>,今天主要在设计思想上进 ...

  6. Aop编程--注解与xml的实现

    一.注解方式 1.首先引入spring对于aop编程的jar支持包,spring框架没有的包请自行在网上下载. aopalliance-alpha1.jar aspectjrt.jar aspectj ...

  7. AOP编程,spring实现及JDK,CGLIB实现

    什么是AOP? AOP(Aspect-OrientedProgramming,面向方面编程)和OOP(Object-Oriented Programing,面向对象编程)思想不同,两者并非对立关系,前 ...

  8. Spring框架--AOP编程

    2 手动实现AOP编程 AOP 面向切面的编程, AOP可以实现"业务代码"与"关注点代码"分离 // 保存一个用户 public void add(User ...

  9. Spring第五篇【cglib、手动实现AOP编程】

    前言 到目前为止,已经简单学习了Spring的Core模块.也会怎么与Struts2框架进行整合了-.于是我们就开启了Spring的AOP模块了-在讲解AOP模块之前,首先我们来讲解一下cglib代理 ...

随机推荐

  1. github page更新后不生效

    昨晚在本地git仓库修改了页面内容后,git push上去,到页面去刷新发现,并没有改变.本来还想着是需要点时间来更新,就再等等. 没想到过了十几分钟后,还是没有更新. 然后同时习惯性地打开了邮箱,发 ...

  2. 关于“Durian”调查问卷的心得体会

    这周我们做了项目着手前的客户需求调查,主要以调查问卷的方式进行.其实做问卷调查并不是想象中的那么简单,首先要确定问卷调查的内容,每一个问题都要经过深思熟虑,字字斟酌,既要切合问卷主要目的,又要简洁扼要 ...

  3. SpringMVC中ApplicationContext中的配置文件的问题(No bean named 'sessionFactory' is defined 已解决)

    在一个SpringMVC项目中, 连着两天不管怎么搞都是一直在报错, 报的最多的就是一个 Servlet.service() for servlet [springDispatcherServlet] ...

  4. DFT

    离散傅里叶变换(Discrete Fourier Transform,缩写为DFT),是傅里叶变换在时域和频域上都呈离散的形式, 将信号的时域采样变换为其DTFT的频域采样.在形式上,变换两端(时域和 ...

  5. swift OC混编工程,xcode断点调试,控制台左侧只有变量名称不显示值,右侧输入po命令,打印除一堆提示

    断点调试 (lldb) po 变量名warning: Swift error in module 项目名.Debug info from this module will be unavailable ...

  6. oracle基本查询入门(二) 子查询

    一.子查询语法 SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table); 子查询在主查询之前 ...

  7. ssh登录忽略known_hosts列表

    编辑 ~/.ssh/config 如果不存在,可以先创建,并且要注意其读写权限 mkdir -p ~/.ssh touch ~/.ssh/config ~/.ssh/config 文件内容如下 Log ...

  8. 记录java版本不兼容的坑,(kafka运行报错)

    启动kafka报错 错误原因是: 由较高版本的jdk编译的java class文件 试图在较低版本的jvm上运行的报错 解决办法是: 查看java版本 C:\Users\Administrator&g ...

  9. abort: no username supplied (see "hg help config")

    abort: no username supplied (see "hg help config") 在hg中输入commit 指令时,如果出现下述结果: $ hg commit ...

  10. Laravel Tinker 使用笔记

    我们知道,Laravel Tinker 提供了命令行式的交互调试途径.使用极其方便直观. 使用: #php artisan tinker 要点: 命令要在一行上输入完成,回车执行.>>&g ...