Spring AOP(Aspect Oriented Programming,面向切面编程)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值