Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)
博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。 ② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。 ③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送ZEEKLOG评论防封脚本,送真活跃粉丝,助你提升文章热度。 群公告里还有全网大赛约稿汇总/博客提效工具集/ZEEKLOG自动化运营脚本 有兴趣的加文末联系方式,备注自己的ZEEKLOG昵称,拉你进群,互相学习共同进步。 文章目录
- Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)
- 1. Spring Boot AOP 的本质是什么?
- 2. JDK vs CGLIB:本质与差异
- 3. AOP 核心入口:AnnotationAwareAspectJAutoProxyCreator
- 4. 核心流程(源码级别)
- 5. MethodInterceptor 调用链模型
- 6. ProxyFactory 与 AdvisedSupport
- 7. JDK 动态代理源码解析
- 8. CGLIB 动态代理源码解析
- 9. Spring Boot 的 AOP 自动装配流程
- 10. 实战:自定义 MethodInterceptor(接口级日志增强)
- 11. 完整 AOP 创建链
- 12. JDK vs CGLIB 对比总结表
- 13. 参考文档
- 结束语
Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)
目录
- AOP 本质与 Spring Boot 中的代理体系
- JDK 与 CGLIB 的本质区别与适用场景
- Spring AOP 代理创建入口:AnnotationAwareAspectJAutoProxyCreator
- AOP 代理的创建流程(源码级调用链)
- 方法拦截链 MethodInterceptor 调用模型深入解析
- ProxyFactory 与 AdvisedSupport 完整结构拆解
- JDK 动态代理源码解析
- CGLIB 子类增强源码解析
- Spring Boot 中的 AOP 自动装配是如何介入的?
- 实战:自定义 MethodInterceptor 实现接口级日志增强
- 流程图、调用链图
- 表格总结(JDK vs CGLIB)
- 参考文档
1. Spring Boot AOP 的本质是什么?
AOP(面向切面)在 Spring Boot 中,本质上是:
🎯 用动态代理包装原始 Bean,让方法执行过程被增强。
核心是两个方案:
| 代理方式 | 适用场景 | 原理 |
|---|---|---|
| JDK Dynamic Proxy | Bean 有接口 | 基于 Proxy.newProxyInstance() 生成实现接口的匿名类 |
| CGLIB | Bean 无接口 | 基于 ASM 生成子类并覆写方法 |
Spring Boot 自动开启 AOP 的入口通常来自:
@ConditionalOnClass({EnableAspectJAutoProxy.class})而真正的 AOP 代理创建由:
AnnotationAwareAspectJAutoProxyCreator
来完成。
2. JDK vs CGLIB:本质与差异
关键差异表格:
| 项目 | JDK 动态代理 | CGLIB |
|---|---|---|
| 代理方式 | 接口代理 | 子类代理 |
| 是否依赖接口 | 必须有接口 | 不需要接口 |
| 性能 | 调用成本低 | 生成类成本高,调用快 |
| final 方法是否可代理 | ❌ 不可 | ❌ 也不可 |
| 复杂度 | 简单 | 高,依赖 asm |
| Spring 默认选择 | 有接口用 JDK | 无接口用 CGLIB |
Spring 的默认策略逻辑为:
if(hasUserSuppliedProxyInterfaces()){return JDK dynamic proxy;}else{returnCGLIB proxy;}3. AOP 核心入口:AnnotationAwareAspectJAutoProxyCreator
这是整个 AOP 的自动代理核心。
它继承关系如下:
BeanPostProcessorAbstractAutoProxyCreatorProxyCreatorSupportAnnotationAwareAspectJAutoProxyCreator
最终,它是一个 BeanPostProcessor,意味着:
⚠️ 代理是在 Bean 初始化阶段创建的,而不是在容器启动时创建的。
流程对应:
postProcessBeforeInitialization → 目标Bean初始化 → postProcessAfterInitialization → 生成代理 Bean 4. 核心流程(源码级别)
代理创建的核心方法在:
AbstractAutoProxyCreator#postProcessAfterInitialization
publicObjectpostProcessAfterInitialization(Object bean,String beanName){if(isInfrastructureClass(bean.getClass()))return bean;// 查找当前 Bean 需要应用的增强(Advice)Object[] specificInterceptors =getAdvicesAndAdvisorsForBean(bean);if(specificInterceptors != DO_NOT_PROXY){// 创建代理returncreateProxy(bean.getClass(), beanName, specificInterceptors, bean);}return bean;}🔥 关键点:代理不是提前创建,而是在初始化后替换 Bean!
这意味着:
⚠️ Bean 在初始化时是真实对象,但被注入到容器中的是代理对象。
5. MethodInterceptor 调用链模型
最终 AOP 逻辑依赖一个拦截链:
List<MethodInterceptor> interceptors 执行流程如下:
ClientProxyInterceptor1Interceptor2Target调用方法invoke()invoke()原始方法调用返回返回返回返回结果ClientProxyInterceptor1Interceptor2Target
Spring 构建的链条类似:
ExposeInvocationInterceptor → AspectJAroundAdvice → MethodBeforeAdvice → AfterReturningAdvice6. ProxyFactory 与 AdvisedSupport
Spring 的代理对象都来自:
ProxyFactory 其核心结构:
publicclassProxyFactoryextendsProxyCreatorSupport{...}而管理 AOP 配置信息的是:
AdvisedSupport 包含:
- 目标类
- 目标对象
- 方法拦截器列表
- 代理方式(JDK/CGLIB)
- 是否提前暴露代理
创建代理示例:
ProxyFactory proxyFactory =newProxyFactory(target); proxyFactory.addAdvice(newLogMethodInterceptor());Object proxy = proxyFactory.getProxy();7. JDK 动态代理源码解析
关键入口:
Proxy.newProxyInstance(classLoader, interfaces, invocationHandler)Spring 使用的 InvocationHandler 是:
JdkDynamicAopProxy 主要实现如下:
publicObjectinvoke(Object proxy,Method method,Object[] args){List<Object> chain =this.advised.getInterceptors(method);if(chain.isEmpty()){return method.invoke(this.advised.getTargetSource().getTarget(), args);}MethodInvocation invocation =newReflectiveMethodInvocation(proxy, target, method, args, chain);return invocation.proceed();}🔍 JDK 代理核心:通过 InvocationHandler 包装方法调用。
8. CGLIB 动态代理源码解析
使用:
Enhancer 核心逻辑:
Enhancer enhancer =newEnhancer(); enhancer.setSuperclass(targetClass); enhancer.setCallback(newMethodInterceptor(){});Spring 中的 CGLIB 代理实现是:
CglibAopProxy.DynamicAdvisedInterceptor 核心代码:
publicObjectintercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy){List<Object> chain =this.advised.getInterceptors(method);MethodInvocation invocation =newCglibMethodInvocation(proxy, target, method, args, chain, methodProxy);return invocation.proceed();}💡 CGLIB 的特点:生成子类 & 使用 ASM 自动生成字节码。
9. Spring Boot 的 AOP 自动装配流程
在 Spring Boot 中,AOP 自动配置来自:
spring-boot-autoconfigure 入口类:
AopAutoConfiguration 其中启用了:
@EnableAspectJAutoProxy(proxyTargetClass =false)说明:
- 如果
proxyTargetClass=false→ 尽量使用 JDK 代理 - 如果用户手动开启:
@EnableAspectJAutoProxy(proxyTargetClass =true)则强制 CGLIB。
10. 实战:自定义 MethodInterceptor(接口级日志增强)
1)定义增强
publicclassLogInterceptorimplementsMethodInterceptor{@OverridepublicObjectinvoke(MethodInvocation invocation)throwsThrowable{System.out.println("Before: "+ invocation.getMethod().getName());Object result = invocation.proceed();System.out.println("After: "+ invocation.getMethod().getName());return result;}}2)创建代理
@ServicepublicclassUserServiceImplimplementsUserService{publicvoidhello(){System.out.println("hello");}}@BeanpublicUserServiceuserServiceProxy(UserServiceImpl target){ProxyFactory factory =newProxyFactory(target); factory.addAdvice(newLogInterceptor());return(UserService) factory.getProxy();}3)运行输出:
Before: hello hello After: hello 11. 完整 AOP 创建链
有切面JDKCGLIBBean 创建完成postProcessAfterInitialization获取 Advisor 列表选择代理方式JdkDynamicAopProxyCglibAopProxy构建 MethodInterceptor 链生成代理对象返回代理 Bean
12. JDK vs CGLIB 对比总结表
| 维度 | JDK 代理 | CGLIB 代理 |
|---|---|---|
| 是否需要接口 | 是 | 否 |
| 性能 | 调用慢,创建快 | 调用快,创建慢 |
| 是否能代理 final 类 | 否 | 否 |
| 是否能代理 final 方法 | 否 | 否 |
| Spring 默认选择 | 有接口 | 无接口 |
| 底层原理 | 反射 + InvocationHandler | ASM + 字节码生成 |
13. 参考文档
- Spring AOP 官方文档
https://docs.spring.io/spring-framework/reference/core/aop.html - Spring Framework 源码(GitHub)
https://github.com/spring-projects/spring-framework - JDK Proxy 文档
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html
结束语

👨💻 关于我
持续学习 | 追求真我
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
感谢订阅专栏 三连文章

掘金点击访问QiunerZEEKLOG点击访问QiunerGitHub点击访问QiunerGitee点击访问Qiuner
| 专栏 | 简介 |
|---|---|
| 📊 一图读懂系列 | 图文并茂,轻松理解复杂概念 |
| 📝 一文读懂系列 | 深入浅出,全面解析技术要点 |
| 🌟持续更新 | 保持学习,不断进步 |
| 🎯 人生经验 | 经验分享,共同成长 |
你好,我是Qiuner. 为帮助别人少走弯路而写博客
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍
如果你遇到了问题,自己没法解决,可以去我掘金评论区问。ZEEKLOG评论区和私信消息看不完 掘金消息少一点.
| 上一篇推荐 | 链接 |
|---|---|
| Java程序员快又扎实的学习路线 | 点击该处自动跳转查看哦 |
| 一文读懂 AI | 点击该处自动跳转查看哦 |
| 一文读懂 服务器 | 点击该处自动跳转查看哦 |
| 2024年创作回顾 | 点击该处自动跳转查看哦 |
| 一文读懂 ESLint配置 | 点击该处自动跳转查看哦 |
| 老鸟如何追求快捷操作电脑 | 点击该处自动跳转查看哦 |
| 未来会写什么文章? | 预告链接 |
|---|---|
| 一文读懂 XX? | 点击该处自动跳转查看哦 |
| 2025年终总结 | 点击该处自动跳转查看哦 |
| 一图读懂 XX? | 点击该处自动跳转查看哦 |