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 框架解耦思想的重要体现

相关推荐
ZouZou老师4 小时前
C++设计模式之适配器模式:以家具生产为例
java·设计模式·适配器模式
用户2190326527354 小时前
Java后端必须的Docker 部署 Redis 集群完整指南
linux·后端
曼巴UE54 小时前
UE5 C++ 动态多播
java·开发语言
VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue音乐管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
程序员鱼皮4 小时前
刚刚,IDEA 免费版发布!终于不用破解了
java·程序员·jetbrains
bcbnb4 小时前
苹果手机iOS应用管理全指南与隐藏功能详解
后端
用户47949283569154 小时前
面试官:DNS 解析过程你能说清吗?DNS 解析全流程深度剖析
前端·后端·面试
幌才_loong4 小时前
.NET8 实时通信秘籍:WebSocket 全双工通信 + 分布式推送,代码实操全解析
后端·.net