zoukankan      html  css  js  c++  java
  • AOP基础:注解方式实现前置通知、后置通知、环绕通知、异常通知、最终通知(demo)

    除了使用xml配置外,还可以使用注解的方式实现上述几种通知。

    LogAspectAnnotation.java:

    package aop.Aspe;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Component("logAnn")
    @Aspect
    public class LogAspectAnnotation {
        @Before("execution(public * springProject.Student.add(..))")
        public void bBefore() {
            System.out.println("@@@前置通知");
        }
        @AfterReturning("execution(public * springProject.Student.add(..))")
        public void bAfter() {
            System.out.println("@@@后置通知");
        }
        @AfterThrowing("execution(public * springProject.Student.add(..))")
        public void bThrowing() {
            System.out.println("@@@异常通知");
        }
        
        //环绕通知 ,参数ProceedingJoinPoint
        @Around("execution(public * springProject.Student.add(..))")
        public void myAround(ProceedingJoinPoint jp  ) {
            //方法之前:前置通知
            System.out.println("《【环绕】方法之前:前置通知");
            
            try {
                //方法执行时
                jp.proceed() ;//执行方法
        
                //方法之前之后:后置通知
                System.out.println("《【环绕】方法之前之后:后置通知");
            }catch(Throwable e) {
                //发生异常时:异常通知
                System.out.println("《【环绕】发生异常时:异常通知");
            }finally {
                //最终通知
                System.out.println("《【环绕】最终通知");
            }
        }
    }

    tips:

    @Component("logAnn"): 把这个类加入ioc容器,id为logAnn。
        必须在xml中,加入xmlns:context="http://www.springframework.org/schema/context"
        然后调用扫描器:<context:component-scan base-package="aop.Aspe"></context:component-scan>
        扫描器 会将 指定的包 中的  @Componet @Service  @Respository   @Controller修饰的类产生的对象 增加到IOC容器中

    @Aspect:  声明这个类是个通知。
           不需要通过扫描器,只需要在xml文件中开启即可:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    @Before("execution(public * springProject.Student.add(..))")
           声明这个方法是个前置通知,关联的业务方法为add。

    @AfterReturning("execution(public * springProject.Student.add(..))")
           
    声明这个方法是个前置通知,关联的业务方法为add。

    @AfterThrowing("execution(public * springProject.Student.add(..))")  
           声明这个方法是个异常通知。
    @Around("execution(public * springProject.Student.add(..))")
           声明这个方法为环绕通知。

    上述各个通知对应的方法名可以随便取。


    如果想要获取目标对象的一些参数,则需要使用一个对象:JointPoint。

    package org.lanqiao.aop;
    
    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    //<bean id="logAnnotation" class="org.lanqiao.aop.LogAspectAnnotation">
    //@Component("logAnnotation")   //将LogAspectAnnotation纳入springIOC容器中
    @Aspect //此类是一个通知
    public class LogAspectAnnotation  {
        
        //前置通知
        @Before("execution(public * addStudent(..))") //属性:定义切点
        public void myBefore(JoinPoint jp) {
            System.out.println("《注解形式-前置通知》:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",参数列表:"+ jp.getArgs().length  );
        }
        //后置通知
        @AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) 
        public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
            System.out.println("《注解形式-后置通知》:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",参数列表:"+  jp.getArgs().length+",返回值:"+returningValue );
        }
        
        /*环绕通知 ,参数ProceedingJoinPoint
        @Around("execution(public * addStudent(..))")
        public void myAround(ProceedingJoinPoint jp  ) {
            //方法之前:前置通知
            System.out.println("《【环绕】方法之前:前置通知");
            
            try {
                //方法执行时
                jp.proceed() ;//执行方法
        
                //方法之前之后:后置通知
                System.out.println("《【环绕】方法之前之后:后置通知");
            }catch(Throwable e) {
                //发生异常时:异常通知
                System.out.println("《【环绕】发生异常时:异常通知");
            }finally {
                //最终通知
                System.out.println("《【环绕】最终通知");
            }
        }*/
        
        //异常通知:如果只捕获特定类型的已存银行,则可以通过第二个参数实现:e
        @AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e")
        public void myException(JoinPoint pj, NullPointerException e) {//此异常通知 只会捕获NullPointerException类型的异常
            System.out.println("&&&&&&《注解形式-异常通知》----e:"+e.getMessage());
        }
        
        //最终通知
        @After("execution(public * addStudent(..))")
        public void myAfter() {
            System.out.println("《[myAfter]注解形式-最终通知-----通知》----");
        }
        
        
    }
    
    

    注解形式的返回值:
    a.声明返回值 的参数名:
      

    @AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) 
        public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
        System.out.println("返回值:"+returningValue );

    b: 注解形式实现aop时,通知的方法的参数不能多、少。

    c: 实现接口形式、注解形式 只捕获声明的特定类型的异常,而其他类型异常不捕获。

    d: 异常通知,可以只在某个特定异常才输出。

    @AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e")
      public void myException(JoinPoint pj, NullPointerException e) {//此异常通知 只会捕获NullPointerException类型的异常
      System.out.println("&&&&&&《注解形式-异常通知》----e:"+e.getMessage());
    }
     
     
     
  • 相关阅读:
    npm run eslint 报错 (87 errors, 0 warnings potentially fixable with the --fix option.)
    vue 项目 webstrom IDE格式化代码规则遵循eslint设置
    VUE:Method definition shorthands are not supported by current JavaScript version解决办法(该方法定义的缺陷是不支持当前的JavaScript版本)
    Flex 布局全解
    前端解析ipa、apk安装包信息 —— app-info-parser
    微信小程序开发
    base64上传到oss
    jQuery 文档操作方法
    学习v-on的使用
    学习vue结合ajax查询出后台数据
  • 原文地址:https://www.cnblogs.com/cq0143/p/10662800.html
Copyright © 2011-2022 走看看