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注解:
@RestControllerpublic 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 begin1、Before
这是执行方法
1、Round end
1、After
1、AfterReturning
由此可见,AOP的顺序是:
- 首先进入Around
- 执行joinPoint.proceed()之前,触发Before
- 然后执行joinPoint.proceed()
- 执行joinPoint.proceed()之后,触发After
- 最后触发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 begin1、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