Spring - AOP - 通知

Spring - AOP - 通知

1. 前置通知

  • @Before():在一个方法执行之前,执行通知。
/**
 * 前置通知,在目标方法执行之前执行。
 * 该注解使用AOP表达式指定通知应用于com.springaop.service.UserService包中所有方法的执行。
 * 
 * @param joinPoint 切点,包含关于执行方法的信息,如方法名、参数等。
 */
@Before("execution(* com.springaop.service.UserService.*(..))")
public void before(JoinPoint joinPoint) {
    // 获取当前执行的方法名
    String name = joinPoint.getSignature().getName();
    // 获取方法参数列表
    Object[] args = joinPoint.getArgs();
    // 获取目标对象,即被通知的对象
    Object target = joinPoint.getTarget();
    // 打印日志,记录方法执行前的信息
    System.out.println("前置通知:" + name + "方法执行前,参数为:" + Arrays.toString(args) + ",目标对象为:" + target);
}

程序输出:

前置通知:addUser方法执行前,参数为:[1],目标对象为:com.springaop.service.UserService@1ec9bd38
addUser:1

2. 后置通知

  • @After():在一个方法执行之后,不考虑其结果,执行通知。
    /**
     * 后置通知,在UserService接口的任何方法执行后调用。
     * 该注解使用AOP表达式指定通知的触发条件,即匹配UserService接口的所有方法。
     * 主要用于记录方法执行后的相关信息。
     *
     * @param joinPoint 切点对象,包含关于执行方法的信息,如方法名、参数等。
     */
    @After("execution(* com.springaop.service.UserService.*(..))")
    public void after(JoinPoint joinPoint) {
        // 获取方法名
        String name = joinPoint.getSignature().getName();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 获取目标对象
        Object target = joinPoint.getTarget();
        // 打印后置通知信息,包括方法名、参数和目标对象
        System.out.println("后置通知:" + name + "方法执行后,参数为:" + Arrays.toString(args) + ",目标对象为:" + target);
    }

程序输出:

addUser:1
后置通知:addUser方法执行后,参数为:[1],目标对象为:com.springaop.service.UserService@4b2c5e02

3. 异常通知

  • @AfterThrowing():在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
    /**
     * 异常处理的切面逻辑。
     * 该方法在UserService接口的实现方法执行过程中发生异常时被调用。
     * 主要用于记录方法执行时出现的异常信息,包括方法名称、参数、目标对象和异常消息。
     *
     * @param joinPoint 切点,包含关于正在执行的方法和目标对象的信息。
     * @param ex        异常对象,代表在方法执行过程中发生的异常。
     */
    @AfterThrowing(pointcut = "execution(* com.springaop.service.UserService.*(..))", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Exception ex) {
        // 获取当前执行方法的名称
        String name = joinPoint.getSignature().getName();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 获取目标对象
        Object target = joinPoint.getTarget();
        // 打印异常通知信息,包括方法名称、参数、目标对象和异常消息
        System.out.println("异常通知:" + name + "方法执行后,参数为:" + Arrays.toString(args) + ",目标对象为:" + target + ",异常信息为:" + ex.getMessage());
    }

程序输出:

addUser:1
异常通知:addUser方法执行后,参数为:[1],目标对象为:com.springaop.service.UserService@2415fc55,异常信息为:addUser error

4. 返回通知

  • @AfterReturning():在一个方法执行之后,只有在方法成功完成时,才能执行通知。
    /**
     * 后置返回通知,用于在UserService接口的任意方法执行完成后执行。
     * 该通知将打印方法名、方法参数、目标对象和方法返回值的信息。
     *
     * @param joinPoint 切点,包含关于执行方法的信息,如方法名、参数等。
     * @param result 方法的返回值,用于在通知中进行操作或记录。
     */
    @AfterReturning(pointcut = "execution(* com.springaop.service.UserService.*(..))", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        // 获取方法名
        String name = joinPoint.getSignature().getName();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 获取目标对象
        Object target = joinPoint.getTarget();
        // 打印方法执行后的相关信息
        System.out.println("返回通知:" + name + "方法执行后,参数为:" + Arrays.toString(args) + ",目标对象为:" + target + ",返回值为:" + result);
    }

程序输出:

addUser:1
返回通知:addUser方法执行后,参数为:[1],目标对象为:com.springaop.service.UserService@34b9f960,返回值为:null

5. 环绕通知

  • @Around():在建议方法调用之前和之后,执行通知。
    /**
     * 基于AOP的切面逻辑,围绕UserService中的方法执行。
     * 使用@Around注解可以控制方法执行前、执行后以及出现异常时的行为。
     *
     * @param joinPoint 切点对象,包含关于目标方法的信息,可以用来调用目标方法。
     * @return 返回目标方法的执行结果。如果执行过程中发生异常,可能会返回null。
     * @throws Throwable 如果目标方法执行过程中抛出异常,这里会重新抛出。
     */
    @Around("execution(* com.springaop.service.UserService.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) {
        // 前置通知:在目标方法执行前执行的操作
        // region 前置通知
        System.out.println("前置通知");
        // endregion

        try {
            // 执行目标方法
            // region 目标方法
            Object result = joinPoint.proceed();
            // endregion

            // 返回通知:在目标方法正常返回后执行的操作
            // region 返回通知
            System.out.println("返回通知:" + result);
            return result;
            // endregion
        } catch (Throwable e) {
            // 异常通知:在目标方法抛出异常时执行的操作
            // region 异常通知
            System.out.println("异常通知:" + e.getMessage());
            // endregion
        } finally {
            // 后置通知:无论目标方法执行是否成功,都会执行的操作
            // region 后置通知
            System.out.println("后置通知");
            // endregion
        }
        // 如果执行流程走到这里,通常是因为目标方法抛出异常且被catch住,或者在try块中的proceed()之前发生异常。
        // 返回null表示方法执行失败。
        return null;
    }

6. 执行顺序

  • 程序正常:前置通知 ===> 目标方法 ===> 返回通知 ===> 后置通知(finally)
  • 程序异常:前置通知 ===> 目标方法 ===> 异常通知 ===> 后置通知(finally)
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值