Aop学习笔记

时间:2021-12-15 04:06:52

在学习编程这段时间我想大家都是习惯了面向过程或者面向对象的思想来编程,较少或者没有接触过面向方面编程的思想。

那么什么是面向方面(Aspect)——其实就是与核心业务处理逻辑无关的切面,例如记录日志、事务控制、缓存处理、权限控制等。

这些行为与商业核心业务逻辑是毫无关系的也就是可以完全剥离出来形成一个统一的解决方案,其实这就是Aop的核心思想。接下

来讲解关于微软提供的Unity组件中的AOP。

一、AOP中的几个概念

1):切面(Aspect):对横切性关注点的抽象,说白了就是对某种功能的抽象,日志、事务、权限等都是一个切面;

2):连接点(Joinpoint):在核心业务逻辑中可以进行切入的点,可以理解为切入点的集合(商业逻辑中可能要切入日志、权限、事务等,这些就是连接点);

3):切入点(Pointcut):指对连接点进行拦截的定义,切入点决定了Advice需要切入的具体连接点,Advice->Pointcut->Joinpoint;

4):通知(Advice):拦截到连接点之后所要做的事情(前置通知、返回后通知、环绕通知、抛出异常后通知等);

5):目标对象(Target Object):需要代理的目标对象,目标对象本身只剩下了干净的业务代码,日志、权限等功能需要AOP切入;

6):代理对象(Proxy Object) : 通过AOP容器产生的对象,是由Target Object与共有的Advice(日志、权限、事务)组成的;

7):织入(Weave):指将切面应用到target对象并导致proxy对象创建的过程称为织入(编译时发生,最终会在.dll文件中生成);

8):引入(Introduction):在不修改类代码的前提下,引入可以在运行期为类动态地添加一些方法或字段(运行时动态植入);

二、三种拦截方式

拦截类型 描述 使用条件
透明代理拦截(Transparent Proxy Interceptor) 实例拦截,代理对象是通过.NET的TransparentProxy/RealProxy创建的 当需要拦截的类型继承自MarshalByRefObject或其实现类
接口拦截(Interface Interceptor) 实例拦截,仅能代理目标对象的一个接口,resolve动态创建目标实例的代理类 当接口及其子类在容器中映射过
虚方法拦截(Virtual Method Interceptor) 类型拦截,动态创建当前拦截类型的派生类的实例而不是当前类型,并在实例上切入行为 仅当虚方法需要被拦截时

以上三种根据自己的使用场景*选择,一般来说使用接口拦截的场景要多一些。以下是优势与劣势对比:

   1):Transparent Proxy Interceptor  

             优势是能拦截目标对象的所有方法包括虚方法、非虚方法或接口;

劣势是目标对象必须直接或间接继承自MarshalByRefObject,如果没有那么只能拦截接口方法,而且这种拦截比常规方法调用要慢。

2):Interface Interceptor

             优势是能够拦截目标接口的任何子类对象,而且比Transparent Proxy Interceptor要快速;

劣势是仅能拦截单一接口中的方法(A继承自接口B和C,如果拦截接口B则只能拦截B中的方法,不能拦截C中的方法),

而且代理对象不能强制类型转换为目标对象类型或目标对象实现的其他接口类型。

3):Virtual Method Interceptor

             优势是比Transparent Proxy Interceptor要快速;

劣势是只能拦截虚方法,而且只能在对象创建时进行拦截,而不能对一个已经存在的对象进行拦截。

            

三、接口拦截简单示例

1):怎么让容器支持拦截?

可以通过Unity自带的API为容器配置拦截特性让容器支持拦截,在UnityContainer的Extensions成员中可以看到InterceptionExtension

1 IUnityContainer container = new UnityContainer();
2 container.AddNewExtension<Interception>();

2):怎么让能够进行拦截的容器拦截需要拦截的接口类型?

需要为容器注册映射类型,使用RegisterType方法

1 container.RegisterType<TestInterface, TestClass>(
2 new Interceptor<InterfaceInterceptor>(),
3 new InterceptionBehavior<UnityLogInterceptBehavior>(),
4 new InterceptionBehavior<UnityCacheInterceptBehavior>());
1  Container.RegisterType(
2 interfaceType,
3 classType,
4 action,
5 new Interceptor<InterfaceInterceptor>(),
6 new InterceptionBehavior(new AccLogInterceptorBehavior()),
7 new InterceptionBehavior(new ExcpLogInterceptorBehavior()));

3):怎么能够让拦截行为生效?

只要有了目标对象的代理对象就能对目标对象的意代理接口中的方法进行拦截

1 var obj = container.Resolve<TestInterface>();   // 针对2中的第一种
1 var obj = container.Resolve(interfaceType, action);   // 针对2中的第二种

三、使用到的DLL

    Microsoft.Practices.Unity.dll

Microsoft.Practices.Unity.Interception.dll

附:

Demo下载路径:http://files.cnblogs.com/files/xy-nb/AopDemo.zip

以上只是对微软提供的Unity组件中Aop学习的一点笔记,比较适合初学者看看;有什么问题大家多多指正,相互学习。