Spring学习(9) AspetJ详解

AspectJ中切入点表达式

  • 语法:@Before(value =“execution(权限修饰符 返回值类型 包名.类名.方法名(参数类型))”)
  • 通配符
    • [*]:
      • 可以代表 任意权限修饰符&返回值类型
      • 可以代表任意的包名、任意的类名、任意的方法名
    • […]:
      • 代表任意的参数类型以及参数个数
  • 重用切入点表达式
    • 使用@PointCut注解,提取可重用的切入点表达式
    • 使用方法名()引入切入点表达式
@Component
@Aspect //标注为切面类
public class MyLogging {
    
    
    //重用切入点表达式
    @Pointcut(value = "execution(* com.zyh.aop.CalcImpl.*(..))")
    public void myPointCut() {
    
    }

    @Before(value = "myPointCut()")
    public void beforeMethod(JoinPoint joinPoint) {
    
    
        //方法名称
        String name = joinPoint.getSignature().getName();
        //获取参数
        Object[] args = joinPoint.getArgs();
        System.out.println("==>Calc中" + name + "方法(),参数:" + Arrays.toString(args));
    }

    @After(value = "myPointCut()")
    public void afterMethod() {
    
    
//        System.out.println("==>Calc中"+methodName+"方法(),结果:"+ res);
        System.out.println("==>Calc方法之后执行");
    }


}

AspectJ中JoinPoint

  • JopinPoint[切入点对象]
  • 作用:
    • 获取方法名称
      • String name = joinPoint.getSignature().getName();
      • joinPoint.getSignature() 获取方法签名[方法名拼接上参数列表]
    • 获取参数
      • Object[] args = joinPoint.getArgs();

AspectJ中通知

  • 前置通知
    • 语法:@Before
    • 执行时机:在指定方法执行之前[如目标方法中有异常,会执行]
      • 指定方法:切入点表达式设置位置
  @Before(value = "myPointCut()")
    public void beforeMethod(JoinPoint joinPoint) {
    
    
        //方法名称
        String name = joinPoint.getSignature().getName();
        //获取参数
        Object[] args = joinPoint.getArgs();
        System.out.println("==>Calc中" + name + "方法(),参数:" + Arrays.toString(args));
    }
  • 后置通知

    • 语法:@After
    • 执行时机:在指定方法执行之后执行[如目标方法中有异常,会执行]
    • 示例代码
    @After(value = "myPointCut()")
    public void afterMethod(JoinPoint joinPoint) {
    
    
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("==>Calc中"+name+"方法之后执行!"+Arrays.toString(args));
    }
  • 返回通知
    • 语法:@AfterReturning
    • 执行时机:指定方法返回结果时执行 [如果目标方法有异常则不执行]
    • 注意:@AfterReturning中returning属性与入参中参数名一致
    • 代码
   @AfterReturning(value = "myPointCut()",returning = "res")
    public void afterReturning(JoinPoint joinPoint,Object res){
    
    
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("[返回通知]==>Calc中"+name+"返回结果执行!结果"+res);
    }

在这里插入图片描述

  • 异常通知
    • 语法:使用@AfterThrowing注解标识
    • 执行时机:指定方法出现异常时执行[如果目标方法没有异常,不执行]
    • 在异常通知中,通过@AfterThrowing注解的throwing属性获取异常信息。Throwable是所有错误和异常的顶级父类,所以在异常通知方法可以捕获到任何错误和异常
    • 如果只是对某种特殊的异常类型感兴趣,可以把参数声明为其他异常的参数类型,然后通知就只在抛出这个类型及其子类的异常时才被执行
    • 注意事项:@AfterThrowing中的throwing属性值与参数名一致
    • 实现在这里插入图片描述在这里插入图片描述
  • 环绕通知[前四个通知整合]
    • 语法:@Around
    • 作用:整合前四个通知
    • 注意:参数中必须使用ProceedingJoinPoint,环绕通知一定要有返回值
 @Around(value = "myPointCut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {
    
    
        //        //方法名称
        String name = joinPoint.getSignature().getName();
        //获取参数
        Object[] args = joinPoint.getArgs();
        Object rs = null;

        try {
    
    

            //前置通知 后置通知[有异常执行] 返回通知[有异常不执行] 异常通知

            System.out.println("[前置通知]==>Calc中" + name + "方法(),参数:" + Arrays.toString(args));

            //触发目标对象的目标方法[对应的加减乘除]
            rs = joinPoint.proceed();

            //返回通知
            System.out.println("[返回通知]==>Calc中" + name + "返回结果执行!结果" + rs);

        } catch (Throwable e) {
    
    
            e.printStackTrace();
            //异常通知
            System.out.println("[异常通知]==>Calc中" + name + "方法,出现异常时执行!异常是:" + e);
        } finally {
    
    
            //后置通知[有异常执行]
            System.out.println("[后置通知]==>Calc中" + name + "方法之后执行!" + Arrays.toString(args));
        }

        return rs;
    }


在这里插入图片描述

切面的优先级

数据可能还需要验证等 ,就涉及到切面优先级问题

  • 语法:@Ordder(value=index)
    • index是int类型,默认值是int可存储的最大值
    • 数值最小,优先级越高
/**添加数据的验证功能
 * @author zengyihong
 * @create 2022--07--03 10:11
 */
@Component
@Aspect
@Order(value = 1)
public class MyValidate {
    
    
    /**
     * 添加数据的验证功能
     */
    @Before(value = "com.zyh.aop.MyLogging.myPointCut()")
    public void before(JoinPoint joinPoint){
    
    
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("-----数据验证的切面----------");
    }



}

猜你喜欢

转载自blog.csdn.net/qq_52797170/article/details/125580091
今日推荐