一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。可以理解为内存中没有这个对象就创建,有就直接返回这个对象。
代理模式(Proxy Pattern) 在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,某些操作需要安全控制),直接访问会给使用者或系统结构带来很多麻烦,我们可以在访问此对象时加上一个该对象的访问层。
⚠️ 注意
代理模式和委派模式比较容易混淆:代理模式是结构模式、委托模式是行为模式。
- 代理 = 包裹 + 控制: 像快递员,帮你拿包裹,顺便检查一下。
- 委托 = 包裹 + 转发: 像邮局柜台,你交给他,他转手就交给快递公司。
快递送货上门是代理,他要对包裹负责,并且要确定送给你;你晚上要加班不方便,让家人帮你去取快递是委托,家人拿了就丢那放着,也可能家人都不一定去拿。
¶功能角度分类
类型 | 场景 | 示例 | 特点 |
---|---|---|---|
远程代理(Remote Proxy) | 访问不同地址空间的对象、远程服务通信 | RMI、gRPC、 | |
虚拟代理(Virtual Proxy) | 创建真实对象的成本较高时,延迟加载(Lazy Load) 只有在真正需要时才创建目标对象 |
图片加载 大文件读取 |
减少资源浪费 提升相应速度 |
保护代理(Protection Proxy) | 权限控制 | 鉴权 | 增强安全性 细颗粒度控制 |
¶根据实现技术分类(Java常见)
类型 | 描述 |
---|---|
静态代理(Static Proxy) | 手动编写代理类,编译时确定 |
动态代理(Dynamic Proxy) | 运行时生成代理类,使用java.lang.reflect.Proxy |
CGLIB代理 | 基于字节玛增强技术,适用于没有接口的类 |
¶代理实现方法
- 静态代理
1 | interface Subject { |
- 动态代理
1 | class Proxy implements InvocationHandler { |
- CBLIB代理(字节增强)
1 | class Proxy implements MethodInterceptor { |
差异对别:
类型 | 是否需要接口 | 是否手动写代理类 | 技术基础 | 应用场景 |
---|---|---|---|---|
静态代理 | 是 | 是 | 接口/抽象类 | 简单封装、学习 |
JDK动态代理 | 是 | 否 | 反射+Proxy |
AOP、Spring(可选) |
CGLIB代理 | 否 | 否 | ASM字节玛增强 | 无接口代理、Spring(默认) |
¶总结
代理模式从功能角度可以分为: 远程代理、虚拟代理、保护代理;从实现技术角度可分为: 静态代理、动态代理(JDK)、CGLIB代理。