代理模式(Proxy Pattern)

一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。可以理解为内存中没有这个对象就创建,有就直接返回这个对象。

代理模式(Proxy Pattern) 在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,某些操作需要安全控制),直接访问会给使用者或系统结构带来很多麻烦,我们可以在访问此对象时加上一个该对象的访问层。

⚠️ 注意
代理模式和委派模式比较容易混淆:

代理模式是结构模式、委托模式是行为模式。

  • 代理 = 包裹 + 控制: 像快递员,帮你拿包裹,顺便检查一下。
  • 委托 = 包裹 + 转发: 像邮局柜台,你交给他,他转手就交给快递公司。

快递送货上门是代理,他要对包裹负责,并且要确定送给你;你晚上要加班不方便,让家人帮你去取快递是委托,家人拿了就丢那放着,也可能家人都不一定去拿。

功能角度分类

类型 场景 示例 特点
远程代理(Remote Proxy) 访问不同地址空间的对象、远程服务通信 RMI、gRPC、
虚拟代理(Virtual Proxy) 创建真实对象的成本较高时,延迟加载(Lazy Load)
只有在真正需要时才创建目标对象
图片加载
大文件读取
减少资源浪费
提升相应速度
保护代理(Protection Proxy) 权限控制 鉴权 增强安全性
细颗粒度控制

根据实现技术分类(Java常见)

类型 描述
静态代理(Static Proxy) 手动编写代理类,编译时确定
动态代理(Dynamic Proxy) 运行时生成代理类,使用java.lang.reflect.Proxy
CGLIB代理 基于字节玛增强技术,适用于没有接口的类

代理实现方法

  • 静态代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Subject {
void request();
}
class RealSubject implements Subject {
void request();
}
class Proxy implements Subject {
private Subject realSubject;

@Override
public void request() {
realSubject.request();
}
}
  • 动态代理
1
2
3
4
5
6
class Proxy implements InvocationHandler {
@Override
pubilc Object invoke(Method method, Object[] args, Object proxy) {
return method.invoke(target, args);
}
}
  • CBLIB代理(字节增强)
1
2
3
4
5
6
7
8
9
10
11
12
class Proxy implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, MethodProxy proxy) {
return proxy.invokeSuper(obj, args);
}
}

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new Proxy());
RealSubject proxy = enhancer.create();
proxy.request();

差异对别

类型 是否需要接口 是否手动写代理类 技术基础 应用场景
静态代理 接口/抽象类 简单封装、学习
JDK动态代理 反射+Proxy AOP、Spring(可选)
CGLIB代理 ASM字节玛增强 无接口代理、Spring(默认)

总结

代理模式从功能角度可以分为: 远程代理、虚拟代理、保护代理;从实现技术角度可分为: 静态代理、动态代理(JDK)、CGLIB代理。