Spring AOP之@Around使用

1,078 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

一、什么是环切@Around

@Around:环绕增强,相当于MethodInterceptor;既可以控制入参,还可以控制原方法的执行和返回值。常常配合ProceedingJoinPoint来使用。ProceedingJoinPoint一般配合环切Around使用,而JoinPoint一般用在@AfterReturning后置,@Before前置等目标方法中使用;Proceedingjoinpoint继承了JoinPoint ,是在JoinPoint的基础上暴露出 proceed 这个方法。

image.png

二、@Around环切使用

访问目标方法的参数 Object[] args = point.getArgs();

用改变后的参数执行目标方法 Object returnValue = point.proceed(args);

@Aspect
@Component
public class AopFunc {
    @Pointcut("execution(* com.daji.aop_test.OriFuncImpl.ori(..))")
    public void modifyReturn() {
    }

    @Around("modifyReturn()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object result = joinPoint.proceed(args);
        return result;
    }

}

execution的使用

  • 任意公共方法的执行:execution(public * *(..))
  • 任何一个以“set”开始的方法的执行:execution(* set*(..))
  • AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
  • 定义在service包里的任意方法的执行: execution(* com.xyz.service. . (..))
  • 定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.xyz.service.. . (..))

三、@Around可以篡改返回值,篡改入参

需要ProceedingJoinPoint的配合;一定要将@Around修饰的方法用Object修饰其返回值,并且返回原方法执行的结果,如下图所示:

image.png 篡改入参一样的道理,只需要篡改下图中的 args数组,然后让其传入proceed中,即可完成篡改入参。

四、@Around执行joinPoint.proceed(args)方法

必须用joinPoint.proceed(Object[] args)方法,将修改后的参数进行回传。如果用joinPoint.proceed()方法,则修改后的参数并不会真正被使用。

五、@Around切不进去

  • 检查是否有如下注解
  • 检查能不能自动跳到被切方法
  • 被切方法是不是public方法
  • 被切方法是不是方法内部调用,AOP只在代理方法从外部调用而不是通过this(避免代理)时才起作用。