Spring AOP

@Before 前置通知

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

    @Before("execution(* com.xyz.myapp.dao.*.*(..))")
    public void doAccessCheck() {
        // ...
    }

}

@AfterReturning 返回通知

当匹配的方法执行正常返回时运行.

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

    @AfterReturning("execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())")
    public void doAccessCheck() {
        // ...
    }

}

获取返回值

当我们想获取到某个方法的返回值时, 可以使用如下方式:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

    @AfterReturning(
        pointcut="execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())",
        returning="retVal")
    public void doAccessCheck(Object retVal) {
        // ...
    }

}

returning 表示返回值类型, 这里使用的是 Object 类型, 我们也可以设置指定类型 例如 List<String>.

@AfterThrowing 异常通知

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

    @AfterThrowing(
        pointcut="execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())",
        throwing="ex")
    public void doRecoveryActions(DataAccessException ex) {
        // ...
    }

}

throwing 表示当抛出的是 DataAccessException 异常时, 才会调用此方法.

@After 后置通知

当匹配的方法执行完成后运行.

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class AfterFinallyExample {

    @After("execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())")
    public void doReleaseLock() {
        // ...
    }

}

@Around 围绕通知

在匹配的方法执行前后执行.

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AroundExample {

    @Around("execution(* com.example.demo.sss.TestService.*())")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("执行目标方法之前...");
        Object retVal = pjp.proceed();
        System.out.println("执行目标方法之后...");
        return retVal + " ---> 1111";
    }

}

该方法的第一个形参必须是 ProceedingJoinPoint 类型, 在方法体中调用 proceed 方法才会执行目标方法; 如果程序没有调用 proceed 方, 目标方法不会执行.

调用 proceed 方法时, 还可以传入一个 Object[] 对象, 该数组中的值将被传入目标方法作为实参. 如果传入的 Object[] 数组长度与目标方法所需要的参数个数不相等, 或者 Object[] 数组元素与目标方法所需参数的类型不匹配, 程序就会抛出异常.

获取通知参数

任何通知方法都可以声明一个类型为 org.aspectj.lang.JoinPoint 的参数, 作为它的第一个参数 JoinPoint 接口提供了许多有用的方法:

  • getArgs(): 返回方法参数.
  • getThis(): 返回代理对象.
  • getTarget(): 返回目标对象.
  • getSignature(): 返回建议的方法的描述.
  • toString(): 打印建议方法的描述.
    原文作者:sc_ik
    原文地址: https://segmentfault.com/a/1190000017235414
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞