之前做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. drupal 用法小结,drupal select ,query ,distinct

    https://api.drupal.org/api/drupal/includes%21actions.inc/function/actions_do/7.x addFileds : 这个更全点: ...

  2. java 用volatile和不用volatile的区别

    在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写.这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值 ...

  3. ThreadPoolExecutor的execute源码分析

    上一篇文章指出,ThreadPoolExecutor执行的步骤如下: 向线程池中添加任务,当任务数量少于corePoolSize时,会自动创建thead来处理这些任务: 当添加任务数大于corePoo ...

  4. 学习C++50条忠告

    1.把C++当成一门新的语言学习: 2.看<Thinking In C++>,不要看<C++变成死相>: 3.看<The C++ Programming Language ...

  5. python之字符串【str】

    #Auther Bob#--*--conding:utf-8 --*-- #定义一个str的对象,有下面两种方法name = 'Bob abc'job = str('it')print(type(na ...

  6. win10下安装oracle11G Examples出错[INS-32025][INS-52001]

    安装oracle examples时提示出错:[INS-32025] 所选安装与指定 Oracle 主目录中已安装的软件冲突.[INS-52001] Oracle Database Examples ...

  7. php 函数中静态变量的问题

    <?php function msg() { static $a = 0; echo $a++, '<br />'; } msg(); msg(); msg(); 上述代码,分别输出 ...

  8. Nmap参数说明

    Nmap(Network Mapper)是一款开放源代码的网络探测和安全审核工具.它的设计目标是快速地扫描大型网络,不适应于单一主机.Nmap使用检测IP数据包来确定访问的主机.提供的服务.数据包的类 ...

  9. 操作系统——MiniDos

    #include <stdio.h> #include <string.h> #include <windows.h> ],token[],ch,sa[]; ]={ ...

  10. maven的pom.xml样例

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...