Spring AOP原理

5 阅读2分钟

一、什么是 AOP?

AOP = Aspect Oriented Programming(面向切面编程)

核心作用:

👉 把“公共逻辑”从业务代码中剥离出来,统一管理。

比如:

  • 日志记录
  • 事务控制
  • 权限校验
  • 性能监控
  • 接口限流

二、Spring AOP 底层原理

Spring AOP 只有一个核心:

动态代理

Spring 在运行时生成代理对象。


三、两种代理方式(重点🔥)

1️⃣ JDK 动态代理(默认)

  • 目标类必须实现接口
  • 基于 java.lang.reflect.Proxy

原理:

接口 → 生成代理类 → 方法调用被拦截

示意图:

ControllerProxy (代理对象)
    ↓
ServiceImpl

2️⃣ CGLIB 动态代理

  • 目标类没有接口时使用
  • 基于继承
  • 通过字节码增强

原理:

生成一个子类
重写方法
在方法前后加增强逻辑

四、Spring AOP 执行流程

以 @Transactional 为例:

步骤 1️⃣ Bean 初始化

Spring 在创建 Bean 时会检查:

是否有 AOP 注解?

如果有:

创建代理对象

步骤 2️⃣ 方法调用

你调用:

userService.save();

实际上调用的是:

Proxy.save();

步骤 3️⃣ 代理内部执行

伪代码:

before();   // 开启事务

target.save();  // 执行真实方法

after();    // 提交事务

如果异常:

rollback();

五、Spring AOP 关键概念

名词解释
Aspect切面
Advice通知(增强逻辑)
JoinPoint连接点(方法)
Pointcut切入点(哪些方法)
Weaving织入

六、五种通知类型

@Before
@After
@AfterReturning
@AfterThrowing
@Around   // 最强

🔥 @Around 最重要

@Around("execution(* com.example.service.*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {

    System.out.println("前置");

    Object result = pjp.proceed();

    System.out.println("后置");

    return result;
}

七、底层源码关键类(面试加分🔥)

作用
ProxyFactory创建代理
JdkDynamicAopProxyJDK代理
CglibAopProxyCGLIB代理
Advisor封装切面
MethodInterceptor方法拦截器

八、Spring AOP 和 AspectJ 区别

Spring AOPAspectJ
原理动态代理字节码修改
织入时机运行时编译时
性能较低更高
功能只支持方法级别支持字段/构造器

九、常见面试追问


1️⃣ 为什么同类方法调用事务失效?

this.save(); // 失效

因为:

AOP 是代理对象生效,this 调用绕过代理。


2️⃣ 为什么 private 方法事务不生效?

因为:

CGLIB 通过重写方法实现增强,private 无法被重写。


3️⃣ Spring 默认用哪种代理?

  • 有接口 → JDK
  • 没接口 → CGLIB
  • Spring Boot 2+ 默认强制 CGLIB

十、完整面试回答模板(直接背🔥)

Spring AOP 的底层原理是基于动态代理实现的。
如果目标类实现接口,则使用 JDK 动态代理;
如果没有接口,则使用 CGLIB 通过继承生成子类。

在 Bean 初始化阶段,Spring 会为需要增强的类创建代理对象。
方法调用时,实际上调用的是代理对象,代理对象内部通过 MethodInterceptor 在方法执行前后织入增强逻辑,比如事务、日志等。

Spring AOP 属于运行时织入,而 AspectJ 属于编译时织入。


十一、画个底层结构图

      ClientProxy (代理对象)
        ↓
   MethodInterceptorTarget Object