Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)

Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)
博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。 ② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。 ③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送ZEEKLOG评论防封脚本,送真活跃粉丝,助你提升文章热度。 群公告里还有全网大赛约稿汇总/博客提效工具集/ZEEKLOG自动化运营脚本 有兴趣的加文末联系方式,备注自己的ZEEKLOG昵称,拉你进群,互相学习共同进步。 

文章目录


Spring Boot 机制四: AOP 代理机制源码级深度解析(JDK / CGLIB 全链路)

目录

  1. AOP 本质与 Spring Boot 中的代理体系
  2. JDK 与 CGLIB 的本质区别与适用场景
  3. Spring AOP 代理创建入口:AnnotationAwareAspectJAutoProxyCreator
  4. AOP 代理的创建流程(源码级调用链)
  5. 方法拦截链 MethodInterceptor 调用模型深入解析
  6. ProxyFactory 与 AdvisedSupport 完整结构拆解
  7. JDK 动态代理源码解析
  8. CGLIB 子类增强源码解析
  9. Spring Boot 中的 AOP 自动装配是如何介入的?
  10. 实战:自定义 MethodInterceptor 实现接口级日志增强
  11. 流程图、调用链图
  12. 表格总结(JDK vs CGLIB)
  13. 参考文档

1. Spring Boot AOP 的本质是什么?

AOP(面向切面)在 Spring Boot 中,本质上是:

🎯 用动态代理包装原始 Bean,让方法执行过程被增强。

核心是两个方案:

代理方式适用场景原理
JDK Dynamic ProxyBean 有接口基于 Proxy.newProxyInstance() 生成实现接口的匿名类
CGLIBBean 无接口基于 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 → AfterReturningAdvice

6. 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 默认选择有接口无接口
底层原理反射 + InvocationHandlerASM + 字节码生成

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

结束语

👨‍💻 关于我

持续学习 | 追求真我

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

感谢订阅专栏 三连文章

image-20251011155556997

掘金点击访问QiunerZEEKLOG点击访问QiunerGitHub点击访问QiunerGitee点击访问Qiuner

专栏简介
📊 一图读懂系列图文并茂,轻松理解复杂概念
📝 一文读懂系列深入浅出,全面解析技术要点
🌟持续更新保持学习,不断进步
🎯 人生经验经验分享,共同成长
你好,我是Qiuner. 为帮助别人少走弯路而写博客

如果本篇文章帮到了你 不妨点个吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍

如果你遇到了问题,自己没法解决,可以去我掘金评论区问。ZEEKLOG评论区和私信消息看不完 掘金消息少一点.
上一篇推荐链接
Java程序员快又扎实的学习路线点击该处自动跳转查看哦
一文读懂 AI点击该处自动跳转查看哦
一文读懂 服务器点击该处自动跳转查看哦
2024年创作回顾点击该处自动跳转查看哦
一文读懂 ESLint配置点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑点击该处自动跳转查看哦
未来会写什么文章?预告链接
一文读懂 XX?点击该处自动跳转查看哦
2025年终总结点击该处自动跳转查看哦
一图读懂 XX?点击该处自动跳转查看哦

Read more

【Linux】网络基础(一)

【Linux】网络基础(一)

文章目录 * 网络发展 * 认识协议 * 🚩网络协议 * 🚩协议分层 * OSI七层协议 * 🚩TCP/IP五层(四层)协议 * 🚩网络传输基本流程 * 🚩数据包的封装和解包 * MAC地址 网络发展 起初计算机是用在军事上的 独立模式: 计算机之间相互独立 网络互联:多台计算机连接在一起实现网络互联 局域网LAN:计算机数量越来越多了,通过交换机和路由器连接在一起 广域网WAN:将远隔千里之外的的计算机连接在一起 所谓局域网广域网是相对概念,我们家庭路由器就可以看作局域网,把家家户户连接的社区就是广域网。社区看作局域网,把社区连接的就是广域网,中国网络看作局域网,连接世界就是广域网 认识协议 协议是一种约定 计算机之间通过光信号电信号交流,通过频率强弱来代表0和1,要想传递不同信息,就要约定好数据格式,比如000代表什么信息 要想多台计算机之间相互通信,就要约定共同的标准,这就是网络协议 🚩网络协议 🚩协议分层 打电话的例子,语言层汉语有协议,通信设备层也有协议 英语之间交流

By Ne0inhk

Flutter 三方库 jaguar 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、全能的工业级嵌入式 HTTP 服务端框架与 REST API 交互引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 jaguar 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、全能的工业级嵌入式 HTTP 服务端框架与 REST API 交互引擎 在鸿蒙(OpenHarmony)系统的端侧服务器化、分布式设备互联监控、或者是需要将鸿蒙应用转变为一个能够提供 API 服务的微型网关(如鸿蒙版物联网中枢)场景中,如何通过一套 Dart 代码构建出极致稳健、带路由拦截、支持 Session 且完全透明的 HTTP 服务?jaguar 为开发者提供了一套工业级的、基于生产环境优化的服务端处理方案。本文将深入实战其在鸿蒙端侧服务化中的应用。 前言 什么是 Jaguar?它不是一个普通的 HTTP 监听器,而是一个专为“速度”与“扩展性”

By Ne0inhk
KaiwuDB社区版 3.1.0 在 Ubuntu 22.04 部署实战:TLS 配置、踩坑复盘与轻量压测

KaiwuDB社区版 3.1.0 在 Ubuntu 22.04 部署实战:TLS 配置、踩坑复盘与轻量压测

KWDB 作为一款易用性不断优化的数据库产品,其 3.1.0 版本在运维脚本、配置管理等方面的升级为部署带来了便利,但新手在单机部署过程中仍易因环境适配、依赖缺失、配置不当等问题踩坑。为帮助开发者快速落地 KWDB 单机环境,本文以 Ubuntu 22.04 为基础环境,从实战角度出发,完整拆解 KWDB 3.1.0 单机部署的全流程:不仅明确版本选型依据和部署目标,还细化了环境核查、安装包获取、依赖配置、部署脚本执行等关键操作,针对性解决部署中的高频问题,并通过服务验证、性能基线测试完成最小化验收,最终实现 “安装即能用、问题有解法、效果可验证” 的部署目标,为 KWDB 入门者提供清晰、可复现的实操指引。 文章目录 * 1. 版本与部署路线怎么选 * 2. 目标:这篇文章读完,能带走哪些“

By Ne0inhk
【Mac 上命令行安装 Claude Code】(Claude 的终端版 AI 编程助手)完整指南

【Mac 上命令行安装 Claude Code】(Claude 的终端版 AI 编程助手)完整指南

文章目录 * 前言 * 方式一:最简单一行命令(强烈推荐) * 方式二:Homebrew 安装(如果你已经用 brew 管理软件) * 方式三:npm 全局安装(适合已有 Node.js 环境) * 首次运行 & 认证(所有方式通用) * 推荐使用技巧 前言 若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:[email protected] Claude Code 是 Anthropic 官方推出的终端 AI 编码代理(CLI 工具),它能直接在你的项目目录里读懂代码库、写/改代码、运行 git、调试、执行 bash 命令等,

By Ne0inhk