news 2026/3/22 2:10:02

【从静态代理到动态代理,再到 AOP(一篇彻底讲透)】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【从静态代理到动态代理,再到 AOP(一篇彻底讲透)】

从静态代理到动态代理,再到 AOP(一篇彻底讲透)

  • 从静态代理到动态代理,再到 AOP(一篇彻底讲透)
    • 一、先从一个最简单的业务开始
      • 1️⃣ 定义接口
      • 2️⃣ 实现类(真正的业务代码)
    • 二、什么是代理?(核心思想)
    • 三、静态代理(最原始的方式)
      • 1️⃣ 手写一个代理类
      • 2️⃣ 使用代理
      • 3️⃣ 执行结果
    • 四、静态代理的问题(非常致命)
    • 五、动态代理登场:代理类让 JVM 帮你生成
    • 六、JDK 动态代理(最常见)
      • ⚠️ 前提条件
      • 1️⃣ InvocationHandler(代理的核心)
      • 2️⃣ 创建代理对象
      • 3️⃣ 执行流程(非常重要)
    • 七、动态代理解决了什么?
    • 八、动态代理的痛点
    • 九、AOP 是什么?
    • 十、AOP 写法(你最熟悉的样子)
      • 1️⃣ 业务类(完全不关心代理)
      • 2️⃣ 切面类
      • 3️⃣ 效果
    • 十一、AOP 和动态代理的真实关系(重点)
    • 十二、一句话总结(建议背下来)
    • 十三、真实开发怎么选?
    • 结尾

从静态代理到动态代理,再到 AOP(一篇彻底讲透)

很多人在学 Spring AOP 的时候会觉得:

“这不就是魔法吗?
为什么加个@Before,方法就被拦截了?”

其实一点都不魔法。
AOP 的本质,就是代理。

这篇文章我们从最原始的静态代理开始,一步步走到动态代理,最后你会发现:
👉AOP 只是把动态代理“包装”得更好用了。


一、先从一个最简单的业务开始

1️⃣ 定义接口

publicinterfaceUserService{voidregister();}

2️⃣ 实现类(真正的业务代码)

publicclassUserServiceImplimplementsUserService{@Overridepublicvoidregister(){System.out.println("注册用户");}}

二、什么是代理?(核心思想)

代理 = 不改原类,在方法前后加逻辑

比如我们想在register()前后加日志:

  • 不想改UserServiceImpl
  • 不想每个方法都手写日志

三、静态代理(最原始的方式)

1️⃣ 手写一个代理类

publicclassUserServiceProxyimplementsUserService{privateUserServicetarget;publicUserServiceProxy(UserServicetarget){this.target=target;}@Overridepublicvoidregister(){System.out.println("【前置】记录日志");target.register();System.out.println("【后置】结束日志");}}

2️⃣ 使用代理

publicclassTest{publicstaticvoidmain(String[]args){UserServicetarget=newUserServiceImpl();UserServiceproxy=newUserServiceProxy(target);proxy.register();}}

3️⃣ 执行结果

【前置】记录日志 注册用户 【后置】结束日志

四、静态代理的问题(非常致命)

假设你现在有:

  • UserService
  • OrderService
  • ProductService

每个都要:

  • 日志
  • 权限
  • 事务

那你要写多少个代理类?

类爆炸
大量重复代码
维护成本极高


五、动态代理登场:代理类让 JVM 帮你生成

核心思想:
“代理类我不写了,运行时自动生成。”


六、JDK 动态代理(最常见)

⚠️ 前提条件

目标类必须有接口


1️⃣ InvocationHandler(代理的核心)

importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;publicclassLogInvocationHandlerimplementsInvocationHandler{privateObjecttarget;publicLogInvocationHandler(Objecttarget){this.target=target;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("【前置】记录日志");Objectresult=method.invoke(target,args);System.out.println("【后置】结束日志");returnresult;}}

👉所有方法,都会走 invoke()


2️⃣ 创建代理对象

importjava.lang.reflect.Proxy;publicclassTest{publicstaticvoidmain(String[]args){UserServicetarget=newUserServiceImpl();UserServiceproxy=(UserService)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),newLogInvocationHandler(target));proxy.register();}}

3️⃣ 执行流程(非常重要)

proxy.register() ↓ JVM 自动生成的代理类 ↓ InvocationHandler.invoke() ↓ 前置逻辑 ↓ 真实方法执行 ↓ 后置逻辑

👉你没写代理类,但 JVM 帮你写了


七、动态代理解决了什么?

✅ 不用手写代理类
✅ 一套逻辑代理所有方法
✅ 横切逻辑高度复用

但问题也来了 👇


八、动态代理的痛点

Proxy.newProxyInstance(...)InvocationHandler.invoke(...)Method.invoke(...)

❌ 写法复杂
❌ 可读性差
❌ 每个项目都要重复造轮子

于是就出现了 ——AOP


九、AOP 是什么?

AOP(面向切面编程)是一种思想
本质仍然是代理

它帮你做了三件事:

  1. 自动创建代理对象
  2. 自动决定“代理哪些方法”
  3. 自动管理生命周期

十、AOP 写法(你最熟悉的样子)

1️⃣ 业务类(完全不关心代理)

@ServicepublicclassUserService{publicvoidregister(){System.out.println("注册用户");}}

2️⃣ 切面类

@Aspect@ComponentpublicclassLoggingAspect{@Before("execution(* com.example.UserService.*(..))")publicvoidbefore(){System.out.println("【前置】记录日志");}@AfterReturning("execution(* com.example.UserService.*(..))")publicvoidafter(){System.out.println("【后置】结束日志");}}

3️⃣ 效果

【前置】记录日志 注册用户 【后置】结束日志

十一、AOP 和动态代理的真实关系(重点)

对比动态代理AOP
是什么技术手段编程思想 + 框架
是否手写
使用难度
底层反射 / 字节码动态代理 / CGLIB

👉Spring AOP 底层,仍然是动态代理


十二、一句话总结(建议背下来)

静态代理:我自己写代理类
动态代理:JVM 帮我写代理类
AOP:我只写规则,代理交给框架


十三、真实开发怎么选?

写业务 → 直接用 AOP
学原理 / 写框架 → 学动态代理


结尾

当你理解了:

  • 静态代理在干嘛
  • 动态代理解决了什么
  • AOP 封装了哪些细节

你就会发现:

AOP 从来不是魔法,它只是“代理的高级用法”。

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

ue 动作拷贝

拷贝 Base Pose在 AnimGraph 中用 “Use Cached Pose” 节点或者 Save Cached Pose这样你就有一份 Base Pose 可以随时取用计算 Additive通过 Control Rig 或者动画资产得到 Additive Pose如果需要放大动作幅度,可以在叠加前乘系数:AdditivePose * 1.5 相…

作者头像 李华
网站建设 2026/3/17 3:49:49

【Android毕设源码分享】基于springboot+Android的智能校园点餐管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/19 0:33:15

Thinkphp和Laravel无人智慧超市购物商城管理系统_niyfl

目录ThinkPHP与Laravel在无人智慧超市系统中的应用技术选型对比智慧超市核心模块实现性能优化策略部署与运维建议项目开发技术介绍PHP核心代码部分展示系统结论源码获取/同行可拿货,招校园代理ThinkPHP与Laravel在无人智慧超市系统中的应用 ThinkPHP作为国内流行的PHP框架&…

作者头像 李华
网站建设 2026/3/13 10:15:18

小程序计算机毕设之基于springboot的校园畅聊交友平台大学生线上聊天交友系统的设计与实(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/13 16:02:01

【课程设计/毕业设计】校园交友网站基于springboot个性化大学生线上聊天交友系统【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/14 9:20:23

「大模型学习黄金书单」认真啃完这些书,一条线速通大模型

说句实在的,很多人以为学大模型就是搞点提示词、调个 API,就能搞定一切。但真想“弄懂它”,甚至“做出点东西”来,不啃几本靠谱的书,真的不行。 我一开始也是刷了一堆教程,收藏了几十个 AI 工具帖&#xf…

作者头像 李华