基于注解的返回通知、异常通知、环绕通知-佟刚老师《Spring4视频教程》学习笔记(19)

一、返回通知(返回通知的一个特点是可以访问到方法的返回值,可以对方法的返回值进行拦截)

思考问题:与后置通知进行比较。后置通知不管目标方法是否抛出异常都能得到执行(因为有异常的捕获机制)。
返回通知,紧挨着目标方法执行的代码,所以要等到目标方法正常执行之后得以执行,并且因为紧挨着目标方法,所以返回通知可以访问到目标方法的返回值。

后置通知:是否可以改变方法的返回值。

我的思考:这样来理解。返回通知可以访问到方法的返回值。

思考问题:能不能改变方法的返回值呢?
我的答案:不能。回家自己尝试一下。

示例代码:

    /**
     * 在方法法正常结束后执行的代码,返回通知是可以访问到方法的返回值的。
     * @param jp
     * @param result
     */
    @AfterReturning(value="execution(public int com.liwei.aop.ArithmeticCalculator.*(int,int))",returning="result")
    public void afterReturnMethod(JoinPoint jp,Object result){
        String method_name = jp.getSignature().getName();
        Object[] args = jp.getArgs();
        System.out.println("【返回通知】被增强处理的方法名:" + method_name + "执行完毕,返回值为:" + result);
    }

二、异常通知
示例代码:

    /**
     * 在目标方法出现异常时会执行的代码。
     * 可以访问到异常对象,且可以指定在出现“特定异常”时再执行通知代码。
     * @param jp
     * @param ex
     */
    @AfterThrowing(value="execution(public int com.liwei.aop.ArithmeticCalculator.*(int,int))",throwing="ex")
    public void afterThrowing(JoinPoint jp,ArithmeticException ex){
        String method_name = jp.getSignature().getName();
        Object[] args = jp.getArgs();
        System.out.println("【异常通知】被增强处理的方法名:" + method_name + "抛出异常,异常消息为:" + ex.getMessage());
    }

三、环绕通知(最像 JDK 的动态代理,而且环绕通知必须写返回值,并且可以修改返回值,并且返回通知必须携带 ProceedingJoinPoint 类型的参数)
示例代码:

package com.liwei.aop.spring;

import java.util.Arrays;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Aspect
@Component
public class ValidateAspect {

    /**
     * 环绕通知需要携带 ProceedingJoinPoint 类型的参数。(必须携带) 
     * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法。
     * 且环绕通知必须有返回值, 返回值即为目标方法的返回值。
     * @param pjd
     * @return
     */
    @Around(value="execution(public int com.liwei.aop.ArithmeticCalculator.add(int, int))")
    public Object aroundMethod(ProceedingJoinPoint pjd){
        Object result = null;
        String method_name = pjd.getSignature().getName();
        Object[] args = pjd.getArgs();
        try {
            // 前置通知
            System.out.println("【 Validate 前置通知】参数验证。。。" + "被验证的方法名为:" + method_name + ",参数为:" + Arrays.asList(args));

            // 执行目标方法
            result = pjd.proceed();

            // 返回通知
            System.out.println("【 Validate 返回通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束,返回值为:" + result);
        } catch (Throwable e) {
            e.printStackTrace();
            // 异常通知
            System.out.println("【 Validate 异常通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束,抛出的异常信息:" + e.getMessage());
        }
        // 后置通知
        System.out.println("【 Validate 后置通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束。" );
        return result;

    }
}

执行结果:
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值