AOP 是 Aspect-Oriented programming 的缩写,中文翻译为面向切面编程,它是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。它和OOP一样是一种编程思想。

AOP基本概念

横切(cross-cutting):与对象核心功能无关的公共行为

关注点(concern):一块我们感兴趣的区域

方面(Aspect):就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

连接点(join point):是程序执行中一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个连接点。

切入点(point cut):本质是一个捕获连接点的结构。在AOP中,可以定义一个切入点来捕获相关方法的调用。

通知(advice):是“切入点”的执行方代码,是执行“方面”的具体逻辑

引入(introduce):为对象引入附加的方法或属性,从而达到修改对象结构的目的

AOP本质
    OOP通过封装、继承及多态等概念来建立一种对象层次结构,用来模式现实事物。因为OOP中每个对象都是独立的,因此当我们需要引入公共行为时(日志、安全、异常),代码显得比较臃肿。而AOP很好的解决了这一问题。它剖开对象内部把”横切”的代码封装成一个“方面”。引用大牛的形象比喻来说“如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。”
    AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程部分是核心关注点,与之关系不大的部分是横切关注点。AOP的作用在于分离系统中各种关注点,将核心关注点和横切关注点分离开来。

AOP实现方式
    实现AOP的方式有两种:一是动态代理技术,二是采用静态织入方式
    动态代理:利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行。一般通过Emit来动态的创建代理类;
    静态织入:通过引入特定的语法来创建“方面”,从而在编译期间就织入了“方面”的代码。目前这种实现方式,都是对编译器扩展。这种实现方式性能是最好的

采用动态代理实现AOP
    在说动态代理之前,我们要看一下之前是怎么实现“横切”的。
    首先,我们有这样一个类,负责处理用户的业务逻辑。

   public interface IUserService
{
bool AddUser(User user);
IList<User> GetUsers();
} public class UserService : IUserService
{
public bool AddUser(User user)
{
Console.WriteLine("添加人员:{0}", user.Name);
return true;
} public IList<User> GetUsers()
{
return new List<User>
{
new User{Name = "张三",BirthDate = DateTime.Now.AddYears(-1)},
new User{Name = "李四",BirthDate = DateTime.Now.AddYears(-2)},
new User{Name = "王五",BirthDate = DateTime.Now.AddYears(-3)},
};
}
}

    现在我们要给所有的核心业务添加日志记录的功能,我们以下几种选择:

1、直接在方法内部添加日志记录的代码

   public class UserService : IUserService
{
public bool AddUser(User user)
{
Console.WriteLine("添加人员:{0}", user.Name);
Console.WriteLine("Log:AddUser"); return true;
} public IList<User> GetUsers()
{
Console.WriteLine("Log:GetUsers");
return new List<User>
{
new User{Name = "张三",BirthDate = DateTime.Now.AddYears(-1)},
new User{Name = "李四",BirthDate = DateTime.Now.AddYears(-2)},
new User{Name = "王五",BirthDate = DateTime.Now.AddYears(-3)},
};
}
}

2、添加一个继承UserServeice的子类,并重写/覆盖父类的方法

  public class MyUserService : UserService
{
public new bool AddUser(User user)
{
base.AddUser(user);
Console.WriteLine("Log:AddUser");
return true;
} public new IList<User> GetUsers()
{
Console.WriteLine("Log:GetUsers");
return base.GetUsers();
} }

3、写一个静态的代理类

首先声明一个拦截器接口

  public interface IInterceptor
{
object Invoke(object obj, string methodName, object[] paramters);
}

然后创建一个日志拦截器

 public class LogInterceptor : IInterceptor
{
public object Invoke(object obj, string methodName, object[] paramters)
{
Console.WriteLine("Log:{0}", methodName); object result = obj.GetType().GetMethod(methodName).Invoke(obj, paramters); return result;
}
}

最后创建静态代理类

        public class MyUserServiceProxy
{
private readonly IInterceptor _interceptor;
private readonly User _user;
public MyUserServiceProxy(User user, IInterceptor interceptor)
{
_user = user;
_interceptor = interceptor;
} public bool AddUser(User user)
{
return (bool)_interceptor.Invoke(_user, "AddUser", new object[] { user });
} public IList<User> GetUsers()
{
return (IList<User>)_interceptor.Invoke(_user, "GetUsers", null); } }

下面调用

var proxy = new AOPTest.MyUserServiceProxy(new AOPTest.User
{
Name = "Khadron",
BirthDate = DateTime.Now
},
new AOPTest.LogInterceptor()); IList<AOPTest.User> users = proxy.GetUsers(); if (users.Count > 0)
{
proxy.AddUser(users[0]);
} Console.ReadKey();

    相对于前面的两种方法,第三种方法算是比较好的了,不过还是不够好,缺点是不仅必须给每个业务类都重写一个包含日志处理的代理类,而且如果还有其他类似日志处理的模块(权限),那还需要在写一个其他代理类,这样做起来不仅工作量大,而且维护起来也十分麻烦。 采用动态代理的方式很好的解决了这个问题,上面说过主要采用Emit来实现,代码太多就不贴了,请查看我的github,这里面实现了一个简单的AOP框架

.NET平台下AOP框架

    动态代理:Castle Dynamic ProxyUnityLOOM.NET

    静态织入:Postsharp(收费)Eos

个人推荐使用 Castle框架,至此结束

AOP原理及其实现的更多相关文章

  1. spring ioc aop 原理

    spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...

  2. SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

    接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...

  3. SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

    AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...

  4. 面试问烂的 Spring AOP 原理、SpringMVC 过程(求求你别问了)

    Spring AOP ,SpringMVC ,这两个应该是国内面试必问题,网上有很多答案,其实背背就可以.但今天笔者带大家一起深入浅出源码,看看他的原理.以期让印象更加深刻,面试的时候游刃有余. Sp ...

  5. spring MVC 及 AOP 原理

    SpringMVC工作原理https://www.cnblogs.com/xiaoxi/p/6164383.htmlspring MVC 原理https://blog.csdn.net/y199108 ...

  6. spring aop 原理学习

    @EnableAspectJAutoProxy: @Import(AspectJAutoProxyRegistrar.class) 实际是创建了一个以org.springframework.aop.c ...

  7. Spring之AOP原理、代码、使用详解(XML配置方式)

    Spring 的两大核心,一是IOC,另一个是AOP,本博客从原理.AOP代码以及AOP使用三个方向来讲AOP.先给出一张AOP相关的结构图,可以放大查看. 一.Spring AOP 接口设计 1.P ...

  8. 34、[源码]-AOP原理-链式调用通知方法

    34.[源码]-AOP原理-链式调用通知方法

  9. 33、[源码]-AOP原理-获取拦截器链-MethodInterceptor

    33.[源码]-AOP原理-获取拦截器链-MethodInterceptor

  10. 31、[源码]-AOP原理-AnnotationAwareAspectJAutoProxyCreato机

    31.[源码]-AOP原理-AnnotationAwareAspectJAutoProxyCreato机

随机推荐

  1. 2017.4.18 linux中执行某文件提示权限不够

    因为没有对start.sh文件的执行权限,所以提示权限不够. 加一个执行权限: chmod +x start.sh 可以看到,执行权限已经有了.此时再执行,就ok了.  

  2. Sending SMS And Dialing Numbers without User Consent(Context is not needed)

    Sending SMS And Dialing Numbers without User Consent Sending SMS does not require context or user in ...

  3. bzoj2115【WC2001】Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2059  Solved: 856 [Submit][Statu ...

  4. 文件json

    import jsondef op_data(filename,dic=None): if dic:#写入进去 with open(filename,'w',encoding='utf-8') as ...

  5. Ubuntu 12.04 的IP 设置

      通过访问 /etc/network/interfaces 实现动态IP 或者静态IP 的设置. vim /et/network/interfaces 1.设置动态IP auto lo iface ...

  6. showModalDialog后如何刷新父页面

    最近一个项目使用到的.在网上查了好久,有的可行,有的就不行.总结一下吧.方案一:父页面:window.showModalDialog('User.jsf?USERCODE='001'&Rnd= ...

  7. CoreImage的模糊滤镜

    //1.原始图片 UIImage * image = [UIImage imageNamed:@"1.jpg"]; /****************core image***** ...

  8. IIS5.1、IIS6.0、IIS7.5中安装配置MVC 3

    本文主要介绍在IIS5.1.IIS6.0.IIS7.5中安装配置MVC 3的具体办法! 正文: IIS5.1 1. 安装Microsoft .net FrameWork 4.0安装包; 2. 安装AS ...

  9. Android下关于消息的推送(9.10)

    1 http://developer.baidu.com/wiki/index.php?title=docs/cplat/push/api  百度云推送 2 http://blog.csdn.net/ ...

  10. ASP.NET CORE RAZOR :将搜索添加到 Razor 页面应用

    https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/search 本文档中,将向索引页面添加搜索功能以实现按“流派”或 ...