菜鸟-创作你的创作

spring — AOP详解_spring aop

下面给你一篇系统、实战向的《Spring AOP 详解》,覆盖原理 → 核心概念 → 注解/配置 → 执行顺序 → 常见场景 → 坑点,适合学习和面试复盘。


一、什么是 AOP?

AOP(Aspect Oriented Programming,面向切面编程)
是一种编程思想,用于将横切关注点(如日志、事务、权限、性能监控)从业务逻辑中分离出来。

👉 核心目标:
不修改原有业务代码,就能给方法“增强功能”


为什么需要 AOP?

传统写法的问题:

public void saveUser() {
    log.info("开始");
    // 业务逻辑
    log.info("结束");
}

缺点:

AOP 解决方案:
👉 把日志、事务等统一抽出来


二、Spring AOP 的本质

一句话总结

Spring AOP = 动态代理 + 切点表达式

Spring AOP 只作用于方法级别(不像 AspectJ 可作用于字段、构造器)。


Spring AOP 两种代理方式

方式说明
JDK 动态代理目标类 实现接口
CGLIB 代理目标类 没有接口(默认方式)
spring.aop.proxy-target-class=true

强制使用 CGLIB


三、AOP 核心概念(必背)

概念说明
Aspect(切面)一个类,封装增强逻辑
JoinPoint(连接点)方法执行的某个点
Pointcut(切点)选中哪些方法
Advice(通知)在何时做什么
Target被代理对象
Proxy代理对象
Weaving织入过程

四、Advice(通知)类型

Spring 提供 5 种通知

通知注解说明
前置通知@Before方法执行前
后置通知@After方法执行后(无论异常)
返回通知@AfterReturning正常返回
异常通知@AfterThrowing抛异常
环绕通知@Around最强,包裹整个方法

五、切点表达式(Pointcut)

最常用:execution

execution(访问修饰符 返回值 包名.类名.方法名(参数))

示例

execution(* com.example.service.*.*(..))

含义:


常见写法速查

execution(* *..service..*(..))

execution(public * *(..))

@annotation(com.example.annotation.Log)


六、基于注解的 AOP(主流)

1️⃣ 启用 AOP

@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {}


2️⃣ 定义切面

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void servicePointcut() {}

    @Before("servicePointcut()")
    public void before(JoinPoint jp) {
        System.out.println("方法前:" + jp.getSignature().getName());
    }

    @AfterReturning(value = "servicePointcut()", returning = "result")
    public void afterReturning(Object result) {
        System.out.println("返回值:" + result);
    }

    @AfterThrowing(value = "servicePointcut()", throwing = "e")
    public void afterThrowing(Exception e) {
        System.out.println("异常:" + e.getMessage());
    }
}


七、环绕通知(重点⭐)

@Around("servicePointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();

    Object result = pjp.proceed(); // 执行目标方法

    long end = System.currentTimeMillis();
    System.out.println("耗时:" + (end - start));

    return result;
}

📌 注意:


八、通知执行顺序

正常执行

@Around
@Before
目标方法
@AfterReturning
@After

异常执行

@Around
@Before
目标方法
@AfterThrowing
@After


九、AOP + 自定义注解(企业常用)

1️⃣ 定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}


2️⃣ 切面使用

@Around("@annotation(log)")
public Object around(ProceedingJoinPoint pjp, Log log) throws Throwable {
    System.out.println("操作:" + log.value());
    return pjp.proceed();
}


3️⃣ 使用

@Log("新增用户")
public void addUser() {}


十、Spring AOP 的限制(高频面试)

同类方法内部调用,AOP 失效

public void a() {
    b(); // 不会走 AOP
}

public void b() {}

原因:
👉 代理对象未生效

解决方案:


十一、AOP 常见应用场景

场景示例
日志记录操作日志、审计
事务管理@Transactional
权限校验登录、鉴权
性能统计方法耗时
防重复提交接口幂等

十二、Spring AOP vs AspectJ

对比Spring AOPAspectJ
实现方式运行时代理编译期 / 类加载期
粒度方法级方法、字段、构造器
性能略低更高
易用性⭐⭐⭐⭐⭐⭐⭐⭐

一句话总结

Spring AOP 适合 90% 企业业务,简单高效

退出移动版