Spring AOP 是什么?JDK 动态代理和 CGLIB 有什么区别?
🧑💻 面试官:Spring AOP 的代理,是不是能拦截一个对象的所有方法?
🙋♂️ 我:可以。代理在方法前后加日志、鉴权或事务。
🧑💻 面试官:那对象在自己的方法里调用 this.save(),为什么切面没有执行?
🙋♂️ 我:可能是切点表达式没有匹配到吧。
🧑💻 面试官:如果匹配没问题,但调用根本没有经过代理,你调整表达式有用吗?
先画出「调用经过谁」。Spring AOP 的关键不是注解写在哪里,而是这一次调用有没有走进代理。
面试速答(60 秒版)
Spring AOP 把日志、鉴权等横切逻辑放到业务方法之外,通常通过代理在匹配的方法调用前后执行增强。
JDK 动态代理基于接口,调用方通过代理暴露的接口访问;CGLIB 通过生成目标类的子类实现代理,因此不能增强无法重写的 final、private 等方法,final 类也不能用这种方式代理。
但选了哪种代理,都要检查调用路径。默认代理模式下,目标对象内部通过 this 调用另一个方法,会绕过代理,相应增强不会再次执行。实际排查时,我会先确认实例是不是容器管理的代理、调用是否经过代理,再查切点和配置。具体默认代理类型还要看 Spring 或 Spring Boot 的配置。

知识点详解:代理为什么能增强外部调用,却接不住内部调用
把业务对象和代理对象分开
假设一个 ReportService 负责生成报表,我们希望记录它的执行耗时。容器可以交给调用方一个代理:请求先进入代理,代理记录开始时间,再调用真正的 ReportService,最后记录结束时间。
业务代码不必在每个方法里复制同一段计时逻辑。切点决定哪些方法适用,增强逻辑决定在调用前、返回后、异常时或整个调用周围做什么。
注意这里存在两个角色:调用方拿到的入口,和真正干活的目标对象。只说「框架给方法加了功能」,容易把这个差别忽略掉。
两种代理,暴露和限制不同
JDK 动态代理实现接口,适合通过接口使用对象;它不是目标类本身的子类。CGLIB 则生成子类,需要能继承目标类、重写相关方法。
因此,CGLIB 不能靠重写增强 final 方法和 private 方法,也不能继承 final 类。不能为了让某一个切面生效,就简单认为「换成 CGLIB 全解决」。
Spring 核心框架与 Spring Boot 的默认配置可能不同,用户也可以强制指定。面试中先讲机制,再说明项目实际配置,比背一句「有接口一定用 JDK」更稳妥。
内部调用为什么绕过去了
假设外部调用 report(),经过代理后进入目标对象;report() 再调用自己的 save()。这第二次调用是在目标对象内部发生的,不会自动回到外面的代理入口。
于是,save() 上匹配的增强没有新的拦截机会。这个问题不是切点匹配失败,也不是 save() 没有执行,而是它执行时走了另一条路。
通常可以把需要独立增强的职责拆到另一个容器管理的对象,让调用重新经过代理。自注入或获取当前代理也有使用条件,并会增加耦合,不能当作默认写法。AspectJ 编织属于不同机制,不要把它与代理式 AOP 混为一谈。
排查时按调用链逐项确认
先确认对象来自容器,而不是自己创建;再检查拿到的是不是代理、代理类型是否符合预期。接着检查方法可见性、final 限制、是否内部调用,最后才看切点表达式与增强顺序。
测试也要从与生产相同的入口调用。直接创建业务对象再调用,即使业务返回正确,也没有验证代理增强。
本题讲 Java/Spring 特有机制,不放 Java 实现代码,也不使用 TS/Python 包装函数冒充 Spring 代理。把调用路径看清楚,反而更容易理解。
本题机制参考:Spring Proxying Mechanisms。
面试官继续追问
AOP 和装饰器有什么关系?
都可以把额外行为放在业务逻辑之外,但运行机制和覆盖范围不同。Python 函数装饰器不能直接证明 Spring 内部调用会被拦截。
CGLIB 能拦截构造方法吗?
不能把普通 Spring AOP 方法增强理解成任意构造过程拦截。它的代理创建与目标方法增强是不同问题。
事务注解失效是不是都因为内部调用?
不是。还要查事务管理器、方法与代理配置、回滚规则和异常是否被吞掉。内部调用只是其中一类。
面试速记卡
- Spring AOP 通常通过代理增强方法调用。
- JDK 基于接口;CGLIB 基于可继承、可重写的类方法。
- this 内部调用绕过代理,不触发新的增强。
- 先查调用路径,再查匹配规则和配置。
公司面试真题
真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。
京东 · 数据开发 / 后端 · 校招
Spring AOP 怎样实现切面功能?(题意整理)
京东数据开发工程师后端一面 ↗
原帖发布于 2025-08-31(秋招记录)美团 · Java后端 · 实习
Java 有哪些动态代理机制?(题意整理)
4.21美团Java实习一二面面经 ↗
面试记录为 2020-04-21、2020-04-24;原帖编辑于 2020-11-14