AOP面向切面编程基础

 参考博客:http://blog.csdn.net/ll666634/article/details/78797344

AOP和OOP的关系 

AOP,可以说是OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。 
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。 
这里写图片描述

横切关注点 
一个关注点(concern)就是一个特定的目的,一块我们感兴趣的区域,一段我们需要的逻辑行为。从技术的角度来说,一个典型的软件系统包含一些核心的关注点和系统级的关注点。举个例子来说,一个信用卡处理系统的核心关注点是借贷/存入处理,而系统级的关注点则是日志、事务完整性、授权、安全及性能问题等,许多关注点——即横切关注点。 

AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。有了AOP,OOP变得立体了。如果加上时间维度,AOP使OOP由原来的二维变为三维了,由平面变成立体了。从技术上来说,AOP基本上是通过代理机制实现的。
这里写图片描述

参考博客:http://blog.csdn.net/xiangwanpeng/article/details/53907738

AOP,即面向切面编程,它是Spring中的两个重要内容之一。它是为了把逻辑代码和处理琐碎事务的代码分离开,以便能够分离复杂度。

设想这样一种需求:要实现一个计算器,除了能够进行加减乘除运算之外,还有两个功能,一是日志功能,即能够记录程序的执行情况;二是验证功能,即对要计算的参数进行验证。 
  传统的实现方法是在每一个方法上都添加日志和验证功能,例如,对于日志功能

这将导致的问题有: 
  1. 代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀,每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。 
  2. 代码分散: 以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块(方法)里多次重复相同的日志代码,如果日志需求发生变化,必须修改所有模块。 
  这正是AOP可以解决的问题,AOP的主要编程对象是切面(Aspect),切面可以模块化横切关注点,例如,上述例子中的日志和验证功能都可以被模块化到特定的切面类中

AOP术语:

切面(Aspect):相当于OOP中的类,就是封装用于横插入系统的功能。例如日志、事务、安全验证等。

通知(Advice):相当于OOP中的方法,是编写实际功能代码的地方。

连接点(Joinpoint):程序执行过程中插入方面的地方。Spring AOP只支持在方法调用和异常抛出中插入方面代码。

切入点(Pointcut):定义通知应该织人到哪些连接点上。通常切入点指的是类或方法名。例如某个通知要应用所有以abc开头的方法中,那么所有满足这个规则的方法都是切入点。

目标(Target):目标类或者目标接口。

代理(Proxy):AOP工作时是通过代理对象来访问目标对象。其实AOP的实现是通过动态代理,离不开代理模式,所以必须要有一个代理对象。

织入(Weaving):在目标对象中插入方面代码的过程就叫做织入。

通知(Advice)类型

  • 前置通知(Before advice) :在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。例如,TestAspect中的doBefore方法
  • 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。例如,TestAspect中的doAfter方法,所以AOPTest中调用BServiceImpl.barB抛出异常时,doAfter方法仍然执行
  • 返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。ApplicationContext中在<aop:aspect>里面使用<after-returning>元素进行声明。
  • 环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。例如,TestAspect中的doAround方法。
  • 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。 ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。例如,TestAspect中的doThrowing方法。

       切入点表达式

  • 通常情况下,表达式中使用”execution“就可以满足大部分的要求。表达式格式如下

例子博客:http://blog.csdn.net/qq_33054511/article/details/53353460

原文地址:https://www.cnblogs.com/gzu-link-pyu/p/8481526.html