Spring AOP 常用功能实现

1. 导入依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 核心通知

package com.example.aspect;

import lombok.SneakyThrows;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1)
@Component
public class RequestAspect {
    @Pointcut("execution(* com.example.controller..*(..))")
    public void pc() {
    }

    /**
     * around通知必须有返回值
     */
    @SneakyThrows
    @Around("com.example.aspect.RequestAspect.pc()")
    public Object around(ProceedingJoinPoint joinPoint) {
        System.out.println("around start");
        Object result = joinPoint.proceed();
        System.out.println("around end");
        return result;
    }

    @Before("pc()")
    public void before() {
        System.out.println("before");
    }

    @After("pc()")
    public void after() {
        System.out.println("after");
    }

    @AfterReturning("pc()")
    public void afterReturning() {
        System.out.println("afterReturning");
    }

    @AfterThrowing("pc()")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }
}
around start
before
@RequestMapping
afterReturning
after
around end

3. 执行顺序

@Around joinPoint.proceed()

@Before @RequestMapping @AfterReturning/@AfterThrowing @After

(目标方法抛出异常,@After后跳出切面往上抛,不会再回到@Around)

@Around

4. 切点表达式

4.1 execution方法签名匹配

返回类型和异常可以省略。

execution(<访问修饰符> <返回类型> <包名.类名.⽅法(⽅法参数)> <异常>)
@Pointcut("execution(* com.example.controller..*(..))")

4.2 @annotation注解匹配

@annotation(注解路径)
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")

4.3 @Pointcut切点表达式

@Pointcut可以定义公共切点表达式,也可以在其他切面类中使用。

@Around("com.example.aspect.RequestAspect.pc()")

5. 动态代理

Spring Boot 中的AOP,2.0之前和Spring一样,2.0之后默认使用CGLIB动态代理。

JDK动态代理是模拟接口实现的方式,CGLIB是模拟子类继承的方式。

如果要使用JDK代理,需要在application.yml中增加如下配置。

spring:
  aop:
    proxy-target-class: false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值