news 2026/10/31 17:31:31

Spring AOP核心机制:代理与拦截揭秘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AOP核心机制:代理与拦截揭秘

在 Spring 开发中,我们经常使用@Transactional、日志切面等功能,但很多人并不清楚它们是如何工作的。
本质上,这些能力都建立在Spring AOP之上。

本文面向准备后端校招面试的同学,聚焦以下核心问题:

  • AOP 的设计初衷是什么?为什么不能只用工具类?
  • Spring AOP 如何通过动态代理实现“织入”?
  • 代理对象在 Bean 生命周期中何时创建?
  • 为什么this.method()调用会导致 AOP 或事务失效?

不展开 AspectJ 或字节码生成细节,只讲清Spring AOP 在面试中最常被考察的核心机制。


一、什么是 AOP?

AOP(Aspect Oriented Programming),即面向切面编程。

在实际开发中,一个业务方法往往不仅包含核心逻辑,还会混入一些通用逻辑,例如:

public void createOrder() { // 记录日志 log.info("create order"); // 权限校验 checkPermission(); // 事务控制 beginTransaction(); orderService.save(); commitTransaction(); }

这些逻辑具有共同特点:

  • 与核心业务无关
  • 在多个方法中重复出现

AOP 的目标就是:将这类横切关注点(Cross-Cutting Concerns)从业务代码中抽离,形成统一的切面(Aspect)。

常见应用场景包括:

  • 日志记录
  • 事务管理
  • 权限校验
  • 性能监控

二、Spring AOP 的核心概念

理解 Spring AOP 需要掌握几个基本术语:

概念说明
Aspect切面,封装横切逻辑的类
Advice通知,具体的增强行为
Pointcut切点,定义哪些方法会被拦截
JoinPoint连接点,程序执行过程中的某个点(如方法调用)
Proxy代理对象,用于拦截方法调用

简单流程:

方法调用 ↓ 切点匹配 ↓ 代理对象拦截 ↓ 执行通知(Advice)

三、Spring AOP 的基本使用

在 Spring 中使用 AOP 非常直接。例如定义一个日志切面:

@Aspect @Component public class LogAspect { @Before("execution(* com.demo.service.*.*(..))") public void before() { System.out.println("before method"); } }

当调用orderService.createOrder()时,Spring 会自动在方法执行前插入日志逻辑。

但关键问题是:

Spring 是如何把切面“织入”到业务方法中的?

答案是:代理对象。


四、Spring AOP 的实现机制

Spring AOP 的底层基于动态代理,主要有两种方式:

代理方式适用条件
JDK 动态代理目标类实现了接口
CGLIB 代理目标类没有接口

Spring 的默认策略是:

优先使用 JDK 动态代理;若无接口,则使用 CGLIB。

代理对象的调用结构如下:

客户端 ↓ 代理对象(Proxy) ↓ 拦截器链(Interceptor Chain) ↓ 目标对象(Target)

所有方法调用实际上都经过代理对象,从而有机会执行切面逻辑。


五、代理对象是什么时候创建的?

这是理解 Spring AOP 的关键。

很多人误以为代理在 Bean 实例化时就生成了,实际上:

代理是在 Bean 初始化完成之后,通过BeanPostProcessor创建的。

具体生命周期流程:

1. 实例化 Bean 2. 依赖注入(populate) 3. 初始化(InitializingBean / init-method) 4. BeanPostProcessor.postProcessAfterInitialization() 5. → 此时判断是否需要创建代理

核心实现类是AbstractAutoProxyCreator,其postProcessAfterInitialization()方法中调用:

wrapIfNecessary(bean, beanName)

若当前 Bean 匹配任意切点,则为其创建代理对象。


六、AOP 方法调用的执行流程

当客户端调用方法时,实际执行路径为:

客户端调用 ↓ 代理对象.invoke() ↓ ReflectiveMethodInvocation.proceed() ↓ 遍历拦截器链(MethodInterceptor) ↓ 依次执行 @Before、@Around 等 Advice ↓ 最终调用目标方法

Spring 将多个通知封装为一个拦截器链(Interceptor Chain),通过责任链模式依次执行。


七、为什么内部调用(this.method())会导致 AOP 失效?

这是校招面试高频问题。

@Service public class OrderService { public void methodA() { this.methodB(); // 内部调用 } @Transactional public void methodB() { // 数据库操作 } }

此时@Transactional不会生效。

原因在于:

Spring AOP 是基于代理实现的,只有通过代理对象的方法调用才会触发切面逻辑。
而this.methodB()是直接调用目标对象的方法,绕过了代理,因此事务(或其他 AOP 逻辑)不会被织入。

解决思路包括:

  • 将methodB拆到另一个 Service 中
  • 通过自注入获取代理实例(@Autowired private OrderService self;)

八、Spring AOP 整体流程回顾

将上述环节串联起来:

1. 容器启动,扫描 @Aspect 注解 2. 注册 AbstractAutoProxyCreator(BeanPostProcessor) 3. Bean 初始化完成后,判断是否匹配切点 4. 若匹配,创建代理对象(JDK / CGLIB) 5. 后续方法调用通过代理进入拦截器链 6. 执行通知逻辑,再调用目标方法

九、面试回答参考

如果面试官问:“Spring AOP 是如何实现的?”

可参考如下回答:

Spring AOP 基于动态代理实现。在 Bean 初始化完成后,Spring 通过BeanPostProcessor(具体是AbstractAutoProxyCreator)判断该 Bean 是否匹配切面定义。如果匹配,则为其创建代理对象(有接口用 JDK 代理,无接口用 CGLIB)。
后续对该 Bean 的方法调用,实际是调用代理对象的方法,代理会将通知封装为拦截器链,在目标方法执行前后插入增强逻辑。
需要注意的是,只有通过代理对象的调用才会触发 AOP,内部调用(如this.xxx())会绕过代理,导致切面失效。


十、总结

Spring AOP 的核心机制可归纳为三点:

  1. 基于动态代理(JDK / CGLIB)实现运行时织入;
  2. 代理对象在BeanPostProcessor.postProcessAfterInitialization()阶段创建;
  3. 只有通过代理对象的方法调用,才会进入拦截器链并执行切面逻辑。

理解这三点,就能解释包括@Transactional失效在内的大多数 AOP 相关面试问题。


欢迎在评论区交流你在 AOP 或 Spring 面试中遇到的问题。
如果你觉得本文帮你理清了原理脉络,欢迎点赞或收藏,方便面试前快速回顾。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 7:30:52

【已解决】ollama导入微调后的gguf模型后胡说八道

【背景】我使用llamafactory这个框架LoRA了微调了Qwen3-8B这个纯文本的大模型,并将LoRA权重和原始的模型权重合并得到最终的模型。然后使用llama.cpp将合并后的权重转换为gguf格式,使用llama.cpp部署这个转换后的gguf模型使用没有问题,根据模…

作者头像 李华
网站建设 2026/10/29 10:23:40

行业新闻动态

类别标题热门评论风向打工人深度观点焦虑与展望AI核心技术OpenAI发布GPT-5.4原生电脑操控能力引发替代焦虑😨 “官方说打工人有福了,我怎么感觉饭碗要保不住了?”📉 “以前AI辅助写代码,现在直接全流程干活&#xff0c…

作者头像 李华
网站建设 2026/10/22 13:10:54

不懂安全的程序员有多被动?一文讲透网络安全的核心价值

我们经常可以听到说要注重网络安全,但到底什么是网络安全?网络安全的重要性你又知道多少呢?今天我们一起来简单聊聊吧! 什么是网络安全? 网络安全(Cyber Security)是指网络系统的硬件、软件及…

作者头像 李华
网站建设 2026/10/22 7:07:18

【MySQL 的数据目录】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、MySQL 的数据目录 1、数据库文件的存放路径2、相关命令目录3、配置文件目录 二、数据库和文件系统的关系 1、查看默认数据库2、数据库在文件系统中的表示3、表…

作者头像 李华
网站建设 2026/10/28 21:42:31

基于BES秃鹰优化算法优化RF构建多输入单输出拟合预测模型

基于BES秃鹰优化算法对随机森林RF算法的最佳树数和叶子数进行优化,建立BES-RF多输入单输出的拟合预测模型。 程序内注释详细直接替换数据就可以用,可学习性强。 程序是matlab语言。 程序可以出拟合预测图,误差图,特征重要性排序图…

作者头像 李华
网站建设 2026/10/17 7:03:55

ai_blog_post

AI 发展的过去、现在与未来:一场技术革命的征程 引言 人工智能(Artificial Intelligence,简称 AI)作为 21 世纪最具颠覆性的技术之一,正在深刻地改变着人类社会的方方面面。从智能手机中的语音助手到自动驾驶汽车&…

作者头像 李华