0
点赞
收藏
分享

微信扫一扫

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);
}

Spring学习(9) AspetJ详解_spring

  • 异常通知
  • 语法:使用@AfterThrowing注解标识
  • 执行时机:指定方法出现异常时执行[如果目标方法没有异常,不执行]
  • 在异常通知中,通过@AfterThrowing注解的throwing属性获取异常信息。Throwable是所有错误和异常的顶级父类,所以在异常通知方法可以捕获到任何错误和异常
  • 如果只是对某种特殊的异常类型感兴趣,可以把参数声明为其他异常的参数类型,然后通知就只在抛出这个类型及其子类的异常时才被执行
  • 注意事项:@AfterThrowing中的throwing属性值与参数名一致
  • 实现
  • Spring学习(9) AspetJ详解_优先级_02

    Spring学习(9) AspetJ详解_优先级_03

  • 环绕通知[前四个通知整合]
  • 语法:@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;
}

Spring学习(9) AspetJ详解_spring_04

切面的优先级

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

  • 语法:@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("-----数据验证的切面----------");
}



}


举报

相关推荐

0 条评论