• (III)AOP:第六节:通知


    一、通知概述

            (1)在具体的连接点上要执行的操作;
            (2)一个切面可以包括一个或者多个通知;
            (3)通知所使用的注解的值往往是切入点表达式;

    二、前置通知

      (1)前置通知:在方法执行之前执行的通知;
      (2)使用 @Before 注解
        /**
          * @Before:将方法指定为前置通知
          * 必须设置 value,其值为 切入点表达式
          * 前置通知:作用于方法执行之前
          */
         @Before(value = "execution(public int  com.spring.aop.ICalc.add(int, int))")
         public void beforeMethod(JoinPoint joinPoint) {
             System.out.println("方法执行之前");
             Object[] args = joinPoint.getArgs();   //获取方法的参数
             String methodName =  joinPoint.getSignature().getName();  //获取方法名
             System.out.println("方法名:" + methodName +  ",参数:" + Arrays.toString(args));
         }
     

    三、后置通知

      (1)后置通知:后置通知是在连接点完成之后执行的,即连接点返回结果或者抛出异常的时候;
      (2)使用 @After 注解;
        /**
          * @After:将方法标注为后置通知
          * 后置通知:作用于方法的 finally 语句块中,即不管有没有异常都会执行
          * @param joinPoint
          */
         @After(value = "execution(public int  com.spring.aop.ICalc.*(int, int))")
         public void afterMethod(JoinPoint joinPoint) {
             System.out.println("方法执行之后");
             Object[] args = joinPoint.getArgs();   //获取方法的参数
             String methodName =  joinPoint.getSignature().getName();  //获取方法名
             System.out.println("方法名:" + methodName +  ",参数:" + Arrays.toString(args));
         }
     

    四、返回通知

      (1)返回通知:无论连接点是正常返回还是抛出异常,后置通知都会执行。如果只想在连接点返回的时候记录日志,应使用返回通知代替后置通知;
      (2)使用 @AfterReturning 注解,在返回通知中访问连接点的返回值;
        ① 在返回通知中,只要将 returning 属性添加到 @AfterReturning 注解中,就可以访问连接点的返回值,该属性的值即为用来传入返回值的参数名称;
          returning属性:告诉Spring使用什么变量来接结果返回值
         ② 必须在通知方法的签名中添加一个同名参数,在运行时 Spring AOP 会通过这个参数传递返回值;
         ③ 原始的切点表达式需要出现在 pointcut 属性中;
        /**
          * @AfterReturning:将方法标注为返回通知;
          * 返回通知:作用于方法执行之后,如果发生了异常,就不再执行
          * 可通过 returning 设置接收方法返回值的变量名
          * 要想在方法中使用,必须在方法的形参中设置和变量名相同的参数名的参数
          * @param joinPoint
          * @param result
          */
         @AfterReturning(value = "execution(public int  com.spring.aop.ICalc.*(int, int))", returning="result")
         public void afterReturningMethod(JoinPoint  joinPoint, Object result) {
             System.out.println("方法返回通知");
             Object[] args = joinPoint.getArgs();                      //获取方法的参数
             String methodName =  joinPoint.getSignature().getName();  //获取方法名
             System.out.println("方法名:" + methodName +  ",参数:" + Arrays.toString(args));
             System.out.println("返回值:"+result);
         }

    五、异常通知

      (1)异常通知:只在连接点抛出异常时才执行异常通知;        
      (2)将 throwing 属性添加到 @AfterThrowing 注解中,也可以访问连接点抛出的异常。
          throwing:告诉Spring使用什么变量来接结果异常信息
                     Throwable 是所有错误和异常类的顶级父类,所以在异常通知方法可以捕获到任何错误和异常。
            (3)如果只对某种特殊的异常类型感兴趣,可以将参数声明为其他异常的参数类型,然后通知就只在抛出这个类型及其子类的异常时才被执行;
        /**
          * @AfterThrowing:将方法标注为异常通知(例外通知)
          * 异常通知(例外通知):作用于方法抛出异常时
          * 可通过throwing设置接收方法返回的异常信息
          * 在参数列表中可通过具体的异常类型,来对指定的异常信息进行操作
          * @param ex
          */
         @AfterThrowing(value = "execution(public int  com.spring.aop.ICalc.*(int, int))",throwing="ex")
         public void afterThrowingMethod(Exception ex) {
             System.out.println("有异常了。");
             System.out.println("message:" + ex);
         }
         public void  afterThrowingMethod(ArithmeticException ex) {        //可以指定异常的类型,根据不同类型的异常,选择不同的操作
             System.out.println("有异常了。");
             System.out.println("message:" + ex);
         }
     

    六、Spring对通知方法的约束

      Spring对通知方法的要求不严格:修改返回值和去掉静态static都照样运行

      但唯一有要求的是方法的参数列表一定不能乱写 原因:通知方法是Spring利用反射调用的,每次调用方法都需要确定这个方法的参数表的值; 参数表上的每一个参数,Spring都得知道是什么。

      举例:

        @After("execution(public int com.achang.inter.impl.MyMathCalculator.*(int,int))")
        public  int logEnd(JoinPoint joinPoint){
            String name = joinPoint.getSignature().getName();
            System.out.println("【" + name + "】方法执行最终完成");
            return 0;
        }

      对于有异常和返回值的方法,指定的异常、结果返回值一定要写大:

     public static void logException(JoinPoint joinPoint,Exception e,Object result){
     }
    
    //Exception e, Object result
    

      

      不然他只接收,你写的异常和返回值类型如:只接受空指针异常和Integer类型

    NullPointerException e
    Integer result
    

      

    七、通知方法的执行顺序

      通知方法的执行顺序:

    正常执行情况:@Before(前置通知)—>@After(后置通知)—>@AfterReturning(正常返回)
    
    异常执行情况:@Before(前置通知)—>@After(后置通知)—>@AfterThrowing(方法异常)
    

      

  • 相关阅读:
    HTTP请求返回状态码详解
    C#-MVC开发微信应用(1)--开始使用微信接口
    码源中国.gitignore忽略文件配置
    Windows Server 2008 R2 下配置证书服务器和HTTPS方式访问网站
    架设证书服务器 及 让IIS启用HTTPS服务
    css设置图片的透明度
    页面通过打开设备判断跳转的链接页面
    sql语句修改字段长度
    【C#】时间戳转换
    C# Linq 交集、并集、差集、去重
  • 原文地址:https://www.cnblogs.com/niujifei/p/15449343.html
Copyright © 2020-2023  润新知