文章目录
0.静态代理与动态代理
https://blog.csdn.net/name_sakura/article/details/123576941
1.引入AOP依赖
spring-boot-starter-aop会引入org.aspectj:aspectjweaver:1.9.7
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.定义注解
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Test {
String name() default "";
}
3.定义切片
以注解作为切入点
@Aspect
@Component
@Order(1) // 顺序,越小越早执行
public class TestAspect {
/**
* 切入点为注解为@Test的方法
*/
@Pointcut(value = "@annotation(com.example.demo.annotation.Test)")
public void pointCut() {
}
@Around(value = "pointCut()")
public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("1、Round begin");
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Test test = method.getAnnotation(Test.class);
System.out.println("1、" + test.name()); // 获取注解的信息
Object obj = joinPoint.proceed();
System.out.println("1、Round end");
return obj;
}
@Before(value = "pointCut()")
public void before(){
System.out.println("1、Before");
}
@After(value = "pointCut()")
public void after(){
System.out.println("1、After");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturning(Object result){
System.out.println("1、AfterReturning");
}
@AfterThrowing(value = "pointCut()", throwing="ex")
public void afterThrowing(Throwable ex) {
System.out.println("1、抛出异常:" + ex);
}
}
以com.example.demo.controller下所有public方法作为切入点
@Aspect
@Component
@Order(2)
public class TestAspect2 {
/**
* 切入点为com.example.demo.controller下的所有public方法
*/
@Pointcut(value = "execution(public * com.example.demo.controller.*.*(..))")
public void pointCut() {
}
@Around(value = "pointCut()")
public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("2、Round begin");
Object obj = joinPoint.proceed();
System.out.println("2、Round end");
return obj;
}
@Before(value = "pointCut()")
public void before(){
System.out.println("2、Before");
}
@After(value = "pointCut()")
public void after(){
System.out.println("2、After");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturning(Object result){
System.out.println("2、AfterReturning");
}
}
4.发送web请求
@RestController
public class AopController {
@RequestMapping("/aop")
@Test(name = "hhhhhhhhhhhhh")
public String aop(){
System.out.println("执行方法");
return "success";
}
}
5.Filter、Interceptor 和 AOP advice 的执行顺序
- Filter 在请求到达 Spring MVC 的 DispatcherServlet 之前执行。它主要用于对请求进行预处理,例如设置编码、验证用户身份、记录日志等。在响应返回给客户端之前,Filter 还可以执行后处理操作。
- Interceptor在 DispatcherServlet 处理请求的过程中执行。具体来说,在请求到达 Controller 之前,Interceptor 的 preHandle 方法会被调用。如果 preHandle 方法返回 true,则请求会继续处理;如果返回 false,则请求会被中断,不会到达 Controller,并且后续的 AOP advice 也不会被执行。请求处理完成后,Interceptor 的 postHandle 方法会被调用,用于进行后续处理。
- AOP advice 是在 Spring 的代理对象中织入的增强逻辑。它可以在方法执行前后、抛出异常时等关键点插入自定义逻辑。在请求到达 Controller 并经过 Interceptor 处理后,如果 Interceptor 没有中断请求,那么 AOP advice 会根据配置在相应的方法执行前后执行。
综合以上各点,Filter、Interceptor和AOP advice的执行顺序大致是:
(1)请求首先通过Filter进行预处理。
(2)然后请求到达Interceptor,首先执行preHandle方法。
(3)如果preHandle方法返回true,请求会继续到达Controller,并在Controller方法执行前后由AOP
advice插入增强逻辑。
6.参考
AOP介绍和使用
https://blog.csdn.net/m0_64188165/article/details/131976727
AOP 的详细说明以及基本的使用
https://blog.csdn.net/qq_41291945/article/details/107448517
Spring 是如何实现 AOP 的?
https://www.zhihu.com/question/484672089