Spring AOP讲解(Pointcut、Before、Around、AfterReturning、After)

本文内容纲要:

- AOP依赖

- @Pointcut

- @Around

- @Before

- @After

- @AfterReturning

- 测试

- 多个AOP执行顺序

AOP依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

@Pointcut

定义切入点,有以下2种方式:

方式一:设置为注解@LogFilter1标记的方法,有标记的方法触发该AOP,没有标记就没有。

@Aspect

@Component

public class LogFilter1Aspect {

@Pointcut(value = "@annotation(com.train.aop.annotation.LogFilter1)")

public void pointCut(){

}

}

附上LogFilter1代码:

@Target(ElementType.METHOD)

@Retention(value = RetentionPolicy.RUNTIME)

public @interface LogFilter1 {

}

对应的Controller方法如下,手动添加@LogFilter1注解:

@RestController

public class AopController {

@RequestMapping("/aop")

@LogFilter1

public String aop(){

System.out.println("这是执行方法");

return "success";

}

}

方式二:采用表达式批量添加切入点,如下方法,表示AopController下的所有public方法都添加LogFilter1切面

@Pointcut(value = "execution(public * com.train.aop.controller.AopController.*(..))")

public void pointCut(){

}

@Around

环绕通知,可以说是使用最频繁的方式,会将整个方法包围起来

@Around(value = "pointCut()")

public Object round(ProceedingJoinPoint joinPoint){

System.out.println("1、Round begin");

Object obj = null;

try {

obj = joinPoint.proceed();

} catch (Throwable throwable) {

throwable.printStackTrace();

}

System.out.println("1、Round end");

return obj;

}

@Before

前置方法,在目标方法执行前触发

@Before(value = "pointCut()")

public void before(){

System.out.println("1、Before");

}

@After

后置方法,与@Before相反,在目标方法执行完毕后执行

@After(value = "pointCut()")

public void after(){

System.out.println("1、After");

}

@AfterReturning

后置通知,在将返回值返回时执行

@AfterReturning(value = "pointCut()", returning = "result")

public void afterReturning(Object result){

System.out.println("1、AfterReturning");

}

测试

接下来执行最开始声明的AopController,输出如下:

1、Round begin

1、Before

这是执行方法

1、Round end

1、After

1、AfterReturning

由此可见,AOP的顺序是:

  1. 首先进入Around
  2. 执行joinPoint.proceed()之前,触发Before
  3. 然后执行joinPoint.proceed()
  4. 执行joinPoint.proceed()之后,触发After
  5. 最后触发AfterReturning

多个AOP执行顺序

当创建了多个自定义注解,并标记到同一个方法上,可以通过设置Order来指定执行顺序。

这边创建一个LogFilter2、LogFilter2Aspect,代码跟上面的例子一样,把“1”改成“2”就行

方式一:添加注解@Order

@Aspect

@Component

@Order(1)

public class LogFilter1Aspect {

}

@Aspect

@Component

@Order(2)

public class LogFilter2Aspect {

}

方式二:实现Ordered接口

@Aspect

@Component

public class LogFilter1Aspect implements Ordered {

@Override

public int getOrder() {

return 1;

}

}

@Aspect

@Component

public class LogFilter2Aspect implements Ordered {

@Override

public int getOrder() {

return 2;

}

}

在Controller代码把2个注解都加上:

@RequestMapping("/aop")

@LogFilter1

@LogFilter2

public String aop(){

System.out.println("这是执行方法");

return "success";

}

执行结果如下:

1、Round begin

1、Before

2、Round begin

2、Before

这是执行方法

2、Round end

2、After

2、AfterReturning

1、Round end

1、After

1、AfterReturning

由此可见,Order越小的越优先执行,但是,After方法反而越后面执行,用一张图表示

1、外层的是LogFilter1,因为Order设置为1,最小优先进入

2、里层的是LogFilter2,因为Order设置为2,所以在LogFilter1后面执行

3、出来的时候,先穿过的是LogFilter2,然后才穿过LogFilter1,这也就是为什么LogFilter2的After方法会先执行

4、用一句话来形容,就是层层包围,层层嵌套

本文内容总结:AOP依赖,@Pointcut,@Around,@Before,@After,@AfterReturning,测试,多个AOP执行顺序,

原文链接:https://www.cnblogs.com/fhblikesky/p/13692689.html

以上是 Spring AOP讲解(Pointcut、Before、Around、AfterReturning、After) 的全部内容, 来源链接: utcz.com/z/362851.html

回到顶部