8.4.5 基于注解的 零配置 方式 6. Around增强处理
@Around
注解用于修饰Around
增强处理, Around
增强处理是功能比较强大的增强处理,它近似等于Before
增强处理和AfterReturning
增强处理的总和, Around
处理既可在执行目标方法之前织入增强动作,也可在执行目标方法之后织入增强动作。
Around增强与Before增强和AfterReturning增强的不同
与Before
增强处理、 AfterReturning
增强处理不同的是, Around
增强处理可以决定目标方法在什么时候执行,如何执行,甚至可以完全阻止目标方法的执行。Around
增强处理可以改变执行目标方法的参数值,也可以改变执行目标方法之后的返回值。
什么时候适合使用Around增强
Around
增强处理的功能虽然强大,但通常需要在线程安全的环境下使用。因此,如果使用普通的Before
增强处理、Afterreturning
增强处理就能解决的问题,则没有必要使用Around
增强处理了。
如果需要目标方法执行之前和之后共享某种状态数据,则应该考虑使用Around
增强处理;尤其是需要改变目标方法的返回值时,则只能使用Around
增强处理了。
使用Value属性指定被织入的切入点
Around
增强处理方法应该使用@Around
来标注,使用@Around
注解时需要指定一个value
属性,该属性指定该增强处理被织入的切入点。
第一个形参必须是ProceedingJoinPoint类型
当定义一个Around
增强处理方法时,该方法至少包含一个形参,并且第一个形参必须是ProceedingJoinPoint
类型
需要显示调用ProceedingJoinPoint参数的proceed方法来执行目标方法
在增强处理方法体内,调用ProceedingJoinPoint
参数的proceed
方法才会执行目标方法,这就是Around
增强处理可以完全控制目标方法的执行时机、执行方式的关键;
如果程序没有调用ProceedingJoinPoint
参数的proceed
方法,则目标方法不会被执行。
执行目标方法时传入参数
调用ProceedingJoinPoint
参数的proceed
方法时,还可以传入一个Object数组
作为参数,该数组中的值将被传入目标方法作为执行方法的实参
。
程序示例
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\Around |
下面的程序定义了一个Around
增强处理。
1 | package org.crazyit.app.aspect; |
上面的程序定义了一个TxAspect
切面,该切面里包含一个Around
增强处理的processTx()
方法,该方法中的代码:Object rvt = jp.proceed(args);
用于回调目标方法,回调目标方法时传入了一个args
数组,但这个args
数组是执行目标方法的原始参数被修改后的结果,这样就实现了对调用参数的修改;rvt = (Integer) rvt * (Integer) rvt;
这行代码则用于改变目标方法的返回值。
本示例程序中依然使用前面的Hellolmpl.java
、 World.java
类,只是主程序增加了输出addUser()
方法返回值的功能。执行主程序,将看到如下效果。
1 | 执行目标方法之前,模拟开始事务... |
从运行结果可以看出,使用Around
增强处理可以取得对目标方法最大的控制权,
- 既可完全控制目标方法的执行,
- 也可改变执行目标方法的参数,
- 还可改变目标方法的返回值。
proceed方法调用目标方法时参数不匹配会出现异常
当调用ProceedingJoinPoint
的proceed
方法时,传入的Object数组
参数值将作为目标方法的参数,如果传入的Object数组
的长度与目标方法所需要参数的个数不相等,或者Object数组
元素与目标方法所需参数的类型不匹配,程序就会出现异常。
为了能获取目标方法的参数的个数和类型,需要增强处理方法能访问执行目标方法的参数。