定义
为其他对象提供一种代理以控制对这个对象的访问
应用场景
- 远程代理:也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实(Binder机制)。
- 保护代理:用来控制真实对象访问时的权限。
- 智能引用代理:当调用目标对象时,代理可以处理其他的一些操作。
UML类图

静态代理
在编写代码期间为每个被代理的对象编写对应的代理类,达到对应的代理功能
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class StaticProxy { public static void main(String... args) {
RealStudent student = new RealStudent(); IStudent s = new StudentProxy(student); s.doHomework(); }
interface IStudent { void doHomework(); }
static class RealStudent implements IStudent {
@Override public void doHomework() { System.out.println("doing homework..."); } }
static class StudentProxy implements IStudent {
private IStudent realStudent;
public StudentProxy(IStudent realStudent) { this.realStudent = realStudent; }
@Override public void doHomework() { if (realStudent != null) { realStudent.doHomework(); } else { } } }
}
|
实例:
WeakHandler
优点:在编译期加入,提前就指定好了谁调用谁,效率高。
缺点:如果要想为多个类进行代理,则需要建立多个代理类,维护难度加大。
动态代理
由于每一个静态代理类只能为一个接口服务,工程中有可能产生很多代理类,所以我们就会想办法可以通过一个代理类完成全部的代理功能,那么我们就需要用动态代理
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class DynamicProxy { public static void main(String... args) { RealStudent student = new RealStudent(); Class<?>[] inters = new Class[]{IStudent.class}; IStudent s = (IStudent) Proxy.newProxyInstance(student.getClass().getClassLoader(), inters, new StudentProxy(student)); s.doHomework(); }
interface IStudent { void doHomework(); }
static class RealStudent implements IStudent {
@Override public void doHomework() { System.out.println("doing homework..."); } }
static class StudentProxy implements InvocationHandler {
private IStudent realStudent;
public StudentProxy(IStudent realStudent) { this.realStudent = realStudent; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (realStudent != null) { return method.invoke(realStudent, args); } else { return null; } } }
}
|
动态代理原理:
运行时按照Class文件标准格式结合JNI的defineClass0()方法生成Proxy匿名代理类,该类实现了需要代理的接口,并返回这个代理类的实例对象给调用者。
1 2
| System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
|
实例:
Retrofit
优点:高扩展性
缺点:
- 实现比静态代理复杂,不好理解
- 要求代理对象必须实现了某个接口