🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 1. 前置增强 (1)前置增强配置。 ```xml <aop:config> <aop:pointcut id="add" expression="execution(public void add(int, int))" /> <aop:aspect ref="aspectLogger"> <aop:before method="printLoggerBefore" pointcut-ref="add" /> </aop:aspect> </aop:config> ``` (2)增强函数。 ```java public void printLoggerBefore(JoinPoint jPoint) { logger.info("\n------增强函数的输出------" + "\n增强方式:前置增强" + "\n目标对象:" + jPoint.getTarget() + "\n目标函数:" + jPoint.getSignature().getName() + "\n目标函数的参数:" + Arrays.toString(jPoint.getArgs())); } ``` (3)测试结果,前置增强函数的输出要在目标函数的前面。 ``` ------增强函数的输出------ 增强方式:前置增强 目标对象:com.learn.spring.aop.service.impl.StudentServiceImpl@515aebb0 目标函数:add 目标函数的参数:[10, 20] ------目标函数的输出------ 30 ``` * 前置增强先于目标函数运行。 * 无论目标函数是否发生异常,前置增强都正常执行,相当于放在`finally`语句块中执行。 * 不能获取目标函数的返回值。 # 2. 最终增强 (1)最终增强配置。 ```xml <aop:config> <aop:pointcut id="add" expression="execution(public void add(int, int))" /> <aop:aspect ref="aspectLogger"> <aop:after method="printLoggerAfter" pointcut-ref="add" /> </aop:aspect> </aop:config> ``` (2)增强函数。 ```java public void printLoggerAfter(JoinPoint jPoint) { logger.info("\n------增强函数的输出------" + "\n增强方式:最终增强" + "\n目标对象:" + jPoint.getTarget() + "\n目标函数:" + jPoint.getSignature().getName() + "\n目标函数的参数:" + Arrays.toString(jPoint.getArgs())); } ``` (3)测试结果,最终增强函数的输出要在目标函数的后面。 ``` ------目标函数的输出------ 30 ------增强函数的输出------ 增强方式:最终增强 目标对象:com.learn.spring.aop.service.impl.StudentServiceImpl@7e07db1f 目标函数:add 目标函数的参数:[10, 20] ``` * 目标函数先于最终增强执行。 * 无论目标函数是否发生异常,最终增强都正常执行。 * 无法获取目标函数的返回值。 # 3. 异常增强 (1)异常增强配置。 ```xml <aop:config> <aop:pointcut id="add" expression="execution(public void add(int, int))" /> <aop:aspect ref="aspectLogger"> <!-- throwing: 目标函数发生的异常,如果发生异常则由printLoggerThrowing函数捕捉 --> <aop:after-throwing method="printLoggerThrowing" pointcut-ref="add" throwing="e" /> </aop:aspect> </aop:config> ``` (2)增强函数。 ```java /** * @param e e的命名与 throwing="e" 要一致 */ public void printLoggerThrowing(JoinPoint jPoint, Exception e) { logger.info("\n------增强函数的输出------" + "\n增强方式:异常增强" + "\n目标对象:" + jPoint.getTarget() + "\n目标函数:" + jPoint.getSignature().getName() + "\n目标函数的参数:" + Arrays.toString(jPoint.getArgs()) + "\n目标函数的异常:" + e); } ``` (3)测试结果,只有当目标函数发生异常时异常增强才执行。 ``` ########## 没有发生异常的结果 ########### ------目标函数的输出------ 30 ########## 发生异常的结果 ########### ------增强函数的输出------ 增强方式:异常增强 目标对象:com.learn.spring.aop.service.impl.StudentServiceImpl@1b7cc17c 目标函数:add 目标函数的参数:[10, -20] 目标函数的异常:java.lang.Exception: (x+y)不能小于0. java.lang.Exception: (x+y)不能小于0. at com.learn.spring.aop.service.impl.StudentServiceImpl.add(StudentServiceImpl.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47) ``` * 只有在目标函数发生异常时才执行。 * 目标函数先于异常增强执行。 * 不能获取目标函数的返回值。 # 4. 后置增强 (1)后置增强配置。 ```xml <aop:config> <aop:pointcut id="sub" expression="execution(public int sub(int, int))" /> <aop:aspect ref="aspectLogger"> <!-- returning: 获取目标函数的返回值,并发送到printLoggerReturning方法中--> <aop:after-returning method="printLoggerReturning" pointcut-ref="sub" returning="result" /> </aop:aspect> </aop:config> ``` (2)增强函数。 ```java /** * @param result result的命名与 returning="result" 要一致 */ public String printLoggerReturning(JoinPoint jPoint, Object result) { logger.info("\n------增强函数的输出------" + "\n增强方式:后置增强" + "\n目标对象:" + jPoint.getTarget() + "\n目标函数:" + jPoint.getSignature().getName() + "\n目标函数的参数:" + Arrays.toString(jPoint.getArgs()) + "\n目标函数的返回值:" + result); return "add-" + result; } ``` (3)测试结果,可以获取目标函数的返回值。 ``` ------目标函数的输出------ 10 ------增强函数的输出------ 增强方式:后置增强 目标对象:com.learn.spring.aop.service.impl.StudentServiceImpl@1283bb96 目标函数:sub 目标函数的参数:[20, 10] 目标函数的返回值:10 ``` * 只有目标函数不发生异常时才执行。 * 目标函数先于后置增强执行。 * 可以获取目标函数的返回值,但不能修改目标函数的返回值,如果目标函数返回`void`,则result为`null`。 # 5. 环绕增强 (1)环绕增强配置。 ```xml <aop:config> <aop:pointcut id="sub" expression="execution(public int sub(int, int))" /> <aop:aspect ref="aspectLogger"> <aop:around method="printLoggerAround" pointcut-ref="sub" /> </aop:aspect> </aop:config> ``` (2)增强方法。 ```java /** * @param jPoint ProceedingJoinPoint接口是JoinPoint的子接口,它只能用在环绕增强中 * @return 环绕增强函数返回的值将作为目标函数的返回值 */ public int printLoggerAround(ProceedingJoinPoint jPoint) throws Throwable { Object[] args = jPoint.getArgs(); logger.info("\n------增强函数的输出------" + "\n增强方式:环绕增强" + "\n目标对象:" + jPoint.getTarget() + "\n目标函数:" + jPoint.getSignature().getName() + "\n目标函数的参数:" + Arrays.toString(jPoint.getArgs())); jPoint.proceed(args); int result = ((int)args[0] - (int)args[1]) * 100; return result; } ``` (3)测试结果,成功修改了目标函数的返回值。 ``` ------增强函数的输出------ 增强方式:环绕增强 目标对象:com.learn.spring.aop.service.impl.StudentServiceImpl@145f66e3 目标函数:sub 目标函数的参数:[20, 10] ------目标函数的输出------ 10 返回结果:1000 ``` * 环绕增强在目标函数前后都执行。 * 环绕增强函数的返回值作为目标函数的返回值,即增强方法可以改变目标函数的返回值(注意:增强并不能获取目标函数的返回值,但能修改)。 * 如果增强函数返回值为`void`,则目标函数的返回值为`null`。