Java动态代理如何实现
2026/8/1 7:34:26 网站建设 项目流程

我的理解:核心,在不改变原来的代码的情况下,如果要实现拓展新的功能,通过代理实现,再调用代理,横向开发

动态代理我的理解:和静态代理作用是一样的,但是静态代理我们代理的是一个角色,动态代理可以代理一类角色

一个动态代理,一般代理某一类业务,可以代理多个类,代理的是接口

首先必须先了解动态代理的优点:

1、代码复用性拉满、所有类共用,不用重复编码

2、易维护

3、解耦彻底:业务只管业务、日志、权限等通用逻辑全部集中管理

4、适合批量全局增强:全接口加监控、全方法加事务,一行业务代码不用改。

还有一个优点:

静态代理:代码提前写好,编译就有 class 文件; 动态代理:代码一行没写,程序跑起来的时候 JVM 临时在内存现写 class,用完就丢,硬盘不留文件。

从头到尾,你没有新建任何代理类的 Java 文件。 程序跑起来之后(运行阶段),JDK/CGLIB 在内存里临时凭空拼出一份全新的 class 字节码,直接交给 JVM 加载使用。 硬盘全程不会多出任何代理类的.java/.class 文件,程序关闭,内存里这份临时 class 直接消失。这就是运行时自动生成

静态代理:手写代理类,少量场景能用,多了必难维护;

动态代理:运行自动生成,一套代码通用,适配绝大多数开发。静态代理有的他都有

静态怕多类、怕改方法;动态怕没接口(JDK)、怕 final(CGLIB)。

从零完整复盘,抛弃复杂术语,一层一层捋顺

1. 核心本质:代理是什么?

不管静态、动态代理,套路永远是: 调用方不直接调用真实业务类,先走代理。 代理负责:日志、权限、事务、耗时统计; 真实业务类只做本职功能,杂活全部剥离。

举例子:你要调用用户新增方法 正常:你 → UserServiceImpl(真实类) 代理模式:你 → 代理类 → UserServiceImpl 好处:不改真实类代码,就能在方法前后加额外功能。

2. 静态代理痛点(引出为什么需要动态代理)

静态代理:你手动新建代理.java 文件。 一个真实业务类,必须手写一个专属代理类。 10 个业务类 = 手写 10 个代理类。 如果业务新增方法,所有代理类必须手动新增对应方法,维护极其麻烦。

静态代理的代理类:编译前就写好,编译完硬盘永久存在代理.class 文件。

3. 动态代理最关键:没有手写代理类

你全程只写 3 类代码: 1)业务接口 2)真实实现类 3)拦截处理器(InvocationHandler) 从头到尾,你没有写任何代理的 Java 文件。 硬盘里不存在代理的.java、代理.class。

重点:运行时生成到底发生了什么?

代码执行到Proxy.newProxyInstance这一行(程序跑起来的瞬间):

  1. JDK 根据接口信息,在内存里拼出来一份全新 class 字节码(代理类);
  2. JVM 加载这份内存里的 class,创建出代理对象;
  3. 你调用代理的任意方法,全部跳转进 invoke 方法;
  4. invoke 写增强逻辑(日志),再调用真实对象的方法;
  5. 程序停止,内存清空,这份临时代理 class 直接消失,硬盘不留任何痕迹。

简单说:代理类没有提前准备,程序跑起来临时现做,用完扔掉。

4. 完整执行链路(JDK 动态代理标准流程)

调用者 → 运行时生成的代理对象 → invoke 拦截方法(前置增强)→ 真实对象执行业务 → 后置增强返回结果

5. 两个动态代理分类区别(极简)

JDK 动态代理

硬性要求:真实类必须实现接口。 运行生成的代理类实现和目标一模一样的接口。 限制:没有接口完全不能用。

CGLIB 动态代理

不需要接口。 运行时生成目标类的子类,靠重写父类方法实现拦截。 限制:final 类不能被继承,无法代理;final、私有方法拦截不到。

6. 最大优势,一句话记住

只写一份拦截增强代码,所有业务类全部复用。 以后新增业务类、新增方法,不用修改代理相关任何代码。 这是动态代理碾压静态代理的核心。

7. 配套生活化重讲

静态代理:每个快递员单独配专属驿站(手写代理),快递员越多驿站越多。 动态代理:只有 1 个通用驿站(handler),没有专属驿站。程序运行时临时给当前快递员搭一个临时驿站(内存生成代理),用完拆掉。无论多少快递员,共用一套驿站规则。

8. 高频误区逐个澄清

  1. 误区:动态代理生成 java 源码 错。只会在内存生成二进制 class 字节码,不会产生.java 文件。
  2. 误区:代理 class 会自动保存在电脑 错。默认只在内存,关闭程序就没。只有配置特殊 JVM 参数,才会把 class 保存到硬盘。
  3. 误区:invoke 执行目标方法用 proxy 错。必须 method.invoke (真实 target, 参数);填 proxy 会无限循环调用。

9. 极简背诵版

  1. 动态代理不用手写代理类,运行时内存临时创建代理 class;
  2. 所有方法被统一拦截,可以无侵入增加日志、事务、权限;
  3. JDK 靠接口,CGLIB 靠继承;
  4. 一份增强代码适配所有类,易维护,是 SpringAOP、事务底层原理。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询