Spring AOP 的实现原理是什么?
未标记
考查重点:代理通知链与调用边界。容器为匹配 Bean 建代理,调用时经通知链再到目标;自调用绕过代理,事务等增强不会自动生效
本题目录
参考答案
核心回答
Spring AOP 主要通过运行时代理实现:容器为符合切面条件的 Bean 创建代理,调用先进入代理,代理根据当前方法匹配通知链,在合适的位置执行增强逻辑,再调用目标方法。日志、事务、指标等横切逻辑因此可以从业务方法中抽出。
这里讨论 Spring Framework 6.2 的代理式 AOP。使用 @Aspect 注解并不意味着已经采用 AspectJ 的字节码织入;Spring AOP 仍然可以只是解析其注解和切点表达式,然后通过代理增强方法执行。
代理与通知链怎样工作
切面描述一组横切逻辑;切点决定哪些方法执行需要匹配;通知定义在执行前、返回后、抛异常时或整个调用周围做什么。Spring 根据相关配置和 Bean 信息组织这些规则,创建代理并拦截外部调用。多个增强形成拦截器链,环绕通知可在调用 proceed() 前后执行逻辑,甚至决定是否继续。
代理主要有两种方式:
JDK动态代理:基于接口生成代理,客户端通过接口调用时进入处理逻辑。CGLIB类代理:通过生成目标类型的子类实现增强,适合没有可用接口等情况,也可以通过配置强制使用。
具体采用哪种代理还受 Spring 配置与上层框架默认值影响,因此不能只凭“类实现了接口”就断言当前应用一定生成 JDK 代理。
哪些调用会绕过增强
最典型的是自调用:方法 a 内部用 this.b() 调用方法 b,调用没有重新经过代理,因此 b 上匹配的事务、缓存等增强不会因这次内部调用自动生效。常见改法是把需要独立增强的行为拆到另一个 Bean,由代理边界发起调用;也可以根据确切场景考虑其他织入方式。
类代理依赖继承和覆盖,所以不能用它增强 final 类或覆盖 final 方法;private 方法也不是可覆盖的增强点。直接 new 出来的普通对象、拿到原始目标对象后直接调用,也不会天然经过 Spring 代理。
常见追问
Spring AOP 和 AspectJ 有何区别? Spring AOP 主要增强方法执行,依赖代理边界;AspectJ 可通过编译期或加载期等方式织入字节码,支持更丰富的连接点。应根据需要的增强范围和构建运行成本选择。
环绕通知里忘记 proceed() 会怎样? 目标方法可能根本不执行。如果目标方法应该执行,增强必须正确传递参数、返回值和异常,否则会改变业务语义。
参考资料
- 国内:JavaGuide / Snailclimb:IoC 与 AOP 详解:借鉴切面、切点与通知的分工,解释正文中代理如何匹配并执行增强。
- 国内:JavaGuide / Snailclimb:Java 代理模式详解:代理对象与目标对象的关系解释调用如何被拦截,以及接口代理和子类代理的区别。
- 国内:JavaGuide / Snailclimb:Spring 中的设计模式:代理模式:参考事务、日志等代理应用场景,将正文的拦截器链与项目中的横切功能联系起来。
- 国外:Spring:Proxying Mechanisms, Spring 6.2:官方代理规则核对自调用为何绕过增强,以及类代理受继承和可见性约束的原因。
- 国外:Spring:Declaring Advice, Spring 6.2:环绕通知部分解释增强如何控制目标调用,并帮助检查遗漏 proceed 或返回值时的行为变化。
相关面经
6 篇平安科技
后端开发工程师简单的介绍一下 Spring 的这种 IOC 和这个 AOP 的一些底层的原理吗?
百度
Agent 应用开发工程师简单讲一下AOP,底层的原理是什么
招银科技
后端开发工程师(AI / Agent 方向)Spring AOP实现原理
法大大
Java 开发工程师AOP讲一下,具体使用场景
亚信科技
后端开发工程师(AI / Agent 方向)介绍一下IOC和AOP
展开剩余 1 篇面经
蚂蚁集团
Agent 应用开发工程师Spring的控制反转、AOP

