[TOC]
- AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- 在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
Pointcut
:切点,决定处理如权限校验、日志记录等在何处切入业务代码中(即织入切面)。切点分为execution
方式和annotation
方式。前者可以用路径表达式指定哪些类织入切面,后者可以指定被哪些注解修饰的代码织入切面。Advice
:处理,包括处理时机和处理内容。处理内容就是要做什么事,比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。Aspect
:切面,即Pointcut
和Advice
。Joint point
:连接点,是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。Weaving
:织入,就是通过动态代理,在目标对象方法中执行处理内容的过程。将Advice应用到Pointcut指定Joint point。
@Aspect
:标识一个切面类- 一个自定义的
AOP
注解可以对应多个切面类,这些切面类执行顺序由@Order
注解管理,该注解后的数字越小,所在切面类越先执行。
- @Pointcut:定义一个切点
- 定义需要拦截的东西,这里介绍两个常用的表达式:一个是使用
execution()
,另一个是使用annotation()
。
@Around
可以自由选择增强动作与目标方法的执行顺序,也就是说可以在增强动作前后,甚至过程中执行目标方法。这个特性的实现在于,调用ProceedingJoinPoint
参数的procedd()
方法才会执行目标方法。@Around
可以改变执行目标方法的参数值,也可以改变执行目标方法之后的返回值。Around
增强处理有以下特点:- 当定义一个
Around
增强处理方法时,该方法的第一个形参必须是ProceedingJoinPoint
类型(至少一个形参)。在增强处理方法体内,调用ProceedingJoinPoint
的proceed
方法才会执行目标方法:这就是@Around
增强处理可以完全控制目标方法执行时机、如何执行的关键;如果程序没有调用ProceedingJoinPoint
的proceed
方法,则目标方法不会执行。 - 调用
ProceedingJoinPoint
的proceed
方法时,还可以传入一个Object[ ]
对象,该数组中的值将被传入目标方法作为实参——这就是Around
增强处理方法可以改变目标方法参数值的关键。这就是如果传入的Object[ ]
数组长度与目标方法所需要的参数个数不相等,或者Object[ ]
数组元素与目标方法所需参数的类型不匹配,程序就会出现异常。
- 当定义一个
@Around
功能虽然强大,但通常需要在线程安全的环境下使用。因此,如果使用普通的Before
、AfterReturning
就能解决的问题,就没有必要使用Around
了。如果需要目标方法执行之前和之后共享某种状态数据,则应该考虑使用Around
。尤其是需要使用增强处理阻止目标的执行,或需要改变目标方法的返回值时,则只能使用Around
增强处理了。
@Before
注解指定的方法在切面切入目标方法之前执行JointPoint
对象很有用,可以用它来获取一个签名,利用签名可以获取请求的包名、方法名,包括参数(通过joinPoint.getArgs()
获取)等
- 指定的方法在切面切入目标方法之后执行。
@AfterReturning
注解可以用来捕获切入方法执行完之后的返回值,对返回值进行业务逻辑上的增强处理。- 该方法中的第二个入参就是被切方法的返回值,在
doAfterReturning
方法中可以对返回值进行增强,可以根据业务需要做相应的封装。
- 当被切方法执行过程中抛出异常时,会进入
@AfterThrowing
注解的方法中执行,在该方法中可以做一些异常的处理逻辑。要注意的是throwing
属性的值必须要和参数一致,否则会报错。该方法中的第二个入参即为抛出的异常。