跳到正文
堆栈茶社
返回

Spring学习笔记 - Spring AOP 使用

更新于:
—次阅读
编辑此页

定义 Aspect

定义一个Aspect,只需要我们定义一个最普通的POJO,然后在类上加上@Aspect注解即可。

@Aspect
public class MyAspect {
}

声明 Pointcut

Pointcut 的声明,依附在@Aspect所标注的Asepct定义类之内,通过使用@Pointcut注解,指定Pointcut表达式之后,将这个指定了相应表达式的注解标注到Aspect定义类的某个方法上即可。

@Aspect
public class MyAspect {
  @Pointcut("execution(void *.method1()) || execution(void *.method2())")
  public void pointcut1(){};
}

Pointcut 声明包含两部分

@Aspect
public class MyAspect {
  @Pointcut("execution(void *.method1())") //Pointcut Expression
  public void pointcut1(){}; //Pointcut Signature
}

上面我们就简单定义了一个pointcut,它将匹配到所有方法名为method1且返回值为void的方法。

Pointcut标志符(Pointcut Designator)

上面例子execution(void *.method1())中的execution即为Pointcut标志符。它表明该Pointcut将以什么样的行为来匹配表达式。

声明Advice

它实际上就是使用@Aspect标注的Aspect定义类中的不同方法,只不过这些方法需要针对不同的Advice类型使用对应的注解进行标注。

除了@DeclareParents比较不同之外,其他用于标注不同类型Advice的注解,全都是方法级别的注解定义,只能用于标注方法定义。同时,各种Advice最终织入到什么位置,是由相应的Pointcut定义决定的。所以我们需要为这些用于标注Advice的注解指定对应的Pointcut定义,可以直接使用的Pointcut表达式,也可以指定上面单独声明的@Pointcut类型的Pointcut Signature。

@Aspect
public class MyAspect {

  @Pointcut("execution(void *.method1()) || execution(void *.method2())")
  public void pointcut1(){};

  @Before("pointcut1()") //使用已经定义的Pointcut签名
  public void doSomething1() {
    System.out.println("do something 1...");
  }

  @After("execution(void *.method1())") //直接使用Pointcut表达式
  public void doSomething2() {
    System.out.println("do something 2...");
  }
}
@AfterThrowing 示例
@Aspect
public class AfterThrowingExample {

  @AfterThrowing(
    pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
    throwing="ex")
  public void doRecoveryActions(DataAccessException ex) {
    // ...
  }

}

它有一个独特的属性throwing,通过它我们可以限定Advice定义方法的参数名,并在方法调用的时候,将相应的异常绑定到具体方法参数上。当然如果不需要访问具体异常,那么我们可以声明没有任何参数的方法。

@AfterThrowing(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doRecoveryActions() {
    // ...
  }
@AfterReturning 示例
@Aspect
public class AfterReturningExample {

  @AfterReturning(
    pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
    returning="retVal")
  public void doAccessCheck(Object retVal) {
    // ...
  }
  
}

它也有一个独特的属性returning,它能获取方法的返回值。当然如果我们不需要方法返回值时,也可以去掉该属性。

@Around 示例
@Aspect
public class AroundExample {

  @Around("com.xyz.myapp.SystemArchitecture.businessService()")
  public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
    // start stopwatch
    Object retVal = pjp.proceed();
    // stop stopwatch
    return retVal;
  }

}

该类型的方法定义中,第一个参数必须是ProceedingJoinPoint类型,我们需要通过ProceedingJoinPoint的proceed()方法继续执行调用链。

Spring AOP 相关笔记

Spring学习笔记 - Spring AOP 概述

Spring学习笔记 - Spring AOP 使用


编辑此页
分享这篇文章:

上一篇
Spring学习笔记 - Spring AOP 概述
下一篇
Java中的强引用、软引用、弱引用、虚引用