Spring AOP底层实现(面试版)

引言

大家好啊,今天我们来讲一下面试中常常遇到的问题--Spring AOP到底是什么,做了什么,使用的好处?许多人就回答一个基于代理模式和JDK动态代理就草草了事,面试官没有得到他想要的答案,自然一直向下深挖,如果面试者无法回答或者突然卡住,给予面试官的感觉就会很差。那么我们下面就来探讨一下吧。

Spring AOP是什么?好处是什么?

Spring AOP(面向切面编程)的底层原理主要基于 代理模式(Proxy Pattern) ,并结合了 动态代理技术 来实现横切关注点(如日志、事务、安全等)与业务逻辑的解耦。其核心思想是在不修改源代码的前提下,对目标方法进行增强。

AOP能够减少重复代码与代码之间的耦合度,而且利于模块未来的扩展性和可维护性。

Spring AOP的底层原理?

Spring AOP核心点就是代理模式 + JDK动态代理/CGLIB 动态代理。

其实就两句话:

① 通过"代理对象"拦截方法调用
② 在方法执行前后织入增强逻辑

核心流程

  • 容器启动

    Spring 扫描到你的 @Aspect@Around@Before 等增强方法,解析成 Advisor(通知器)

  • Bean 创建阶段

    当某个 Bean 匹配了 Advisor 的 Pointcut 规则,Spring 会在 BeanPostProcessor(具体是 AnnotationAwareAspectJAutoProxyCreator 中决定 ------ 是否需要为这个 Bean 创建代理对象

  • 代理对象创建

    Spring 根据目标类是否有接口,选择:

    • 有接口 → JDK 动态代理
    • 无接口 → CGLIB 代理(基于子类)
  • 代理对象拦截方法调用

    当你调用 bean.xxx() 时,其实调用的是代理对象 → 执行增强链 → 最后执行目标方法。

    简单来说,就是spring启动的时候会扫一遍那些AOP的切面注解,有bean匹配了相关规则,就会根据是否有实现接口来给他匹配不同的动态代理模式。当该bean调用相关方法,则就会被拦截实现相关增强。

代理模式的选择

1. JDK 动态代理(基于接口)

要求目标类必须实现至少一个接口 。Spring 会为目标对象创建一个实现了相同接口的代理对象。使用 java.lang.reflect.ProxyInvocationHandler 实现,代理类的父类是Proxy 。方法调用时,通过 invoke() 方法拦截,并在其中加入切面逻辑。

Java不允许多继承,代理对象的父类是Proxy,所以只能基于接口实现。

2. CGLIB 动态代理(基于子类)

当目标类 没有实现接口 时,Spring 默认使用 CGLIB。CGLIB 通过继承目标类,生成子类(代理类),并重写其非 final 方法。代理类在重写的方法中插入切面逻辑。需要引入 cglib 依赖(Spring Boot 中已自动包含)。

总的来说,无论是哪种动态代理,执行相关bean的增强方法时,都是执行相关代理对象的方法,里面包含了增强逻辑和原有逻辑。

Spring AOP的织入时机

Spring AOP 是 运行时代理(Runtime Weaving),不是编译时或类加载时织入(如 AspectJ)。

具体流程:

  1. 容器启动时,解析所有 @Aspect 切面类。
  2. 根据 @Pointcut 表达式匹配目标 Bean 的方法。
  3. 对匹配的 Bean 创建代理对象(JDK 或 CGLIB)。
  4. 将代理对象注册到 Spring 容器中,后续注入的是代理对象而非原始对象。
  5. 调用方法时,通过代理对象触发通知逻辑。

这个流程上面说过了,这里再按步骤说一遍,但是重点说的是代理时机,是运行时代理!!!!

总结

Spring AOP 的底层原理可以概括为:

通过动态代理(JDK 或 CGLIB)在运行时为目标 Bean 生成代理对象,并在方法调用前后织入切面逻辑,从而实现非侵入式的功能增强。

这种设计既保持了代码的清晰性,又实现了关注点分离,是 Spring 框架解耦思想的重要体现

相关推荐
风象南7 小时前
我把大脑开源给了AI
人工智能·后端
哈里谢顿10 小时前
1000台裸金属并发创建中的重难点问题分析
面试
哈里谢顿10 小时前
20260303面试总结(全栈)
面试
橙序员小站12 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
怒放吧德德12 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆13 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
开心就好202515 小时前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
悟空码字15 小时前
告别“屎山代码”:AI 代码整洁器让老项目重获新生
后端·aigc·ai编程
小码哥_常15 小时前
大厂不宠@Transactional,背后藏着啥秘密?
后端
奋斗小强15 小时前
内存危机突围战:从原理辨析到线上实战,彻底搞懂 OOM 与内存泄漏
后端