栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring学习(9) AspetJ详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring学习(9) AspetJ详解

  • AspectJ中切入点表达式
  • AspectJ中JoinPoint
  • AspectJ中通知
  • 切面的优先级

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可存储的最大值
    • 数值最小,优先级越高
@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("-----数据验证的切面----------");
    }



}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1005589.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号