Java 有两种代理方式,一种是静态代理,另一种是动态代理。对于静态代理,其实就是通过依赖注入,对对象进行封装,不让外部知道实现的细节。很多 API 就是通过这种形式来封装的。
代理模式结构图(图片来自《大话设计模式》)

下面看下两者在概念上的解释:
静态代理
-
静态代理类:由程序员创建或者由第三方工具生成,再进行编译;在程序运行之前,代理类的.class文件已经存在了。
-
静态代理类通常只代理一个类。
-
静态代理事先知道要代理的是什么。
动态代理
-
动态代理类:在程序运行时,通过反射机制动态生成。
-
动态代理类通常代理接口下的所有类。
-
动态代理事先不知道要代理的是什么,只有在运行的时候才能确定。
-
动态代理的调用处理程序必须事先InvocationHandler接口,及使用Proxy类中的newProxyInstance方法动态的创建代理类。
-
Java动态代理只能代理接口,要代理类需要使用第三方的CLIGB等类库。
动态代理的好处
Java动态代理的优势是实现无侵入式的代码扩展,也就是方法的增强;让你可以在不用修改源码的情况下,增强一些方法;在方法的前后你可以做你任何想做的事情(甚至不去执行这个方法就可以)。此外,也可以减少代码量,如果采用静态代理,类的方法比较多的时候,得手写大量代码。
动态代理实例
静态代理的实例这里就不说了,比较简单。在 java 的 java.lang.reflect 包下提供了一个 Proxy 类和一个 InvocationHandler 接口,通过这个类和这个接口可以生成 JDK 动态代理类和动态代理对象。下面讲讲动态代理的实现。
先定义一个接口:
public interface Person { void setName(String name); }
再定义一个学生 Student 类来实现 Person 接口,每一个学生都有一个自己的名字:
public class Student implements Person { private String mName; public Student(String name) { mName = name; } public void setName(String name) { mName = name; } }
Student 类中,定义了一个私有变量 mName,用来表示 Student 的名字。接下去定义一个代理 handler,就是用来帮我们处理代理的 :
public class PersonHandler<T> implements InvocationHandler { // 代理的目标对象 private T mTarget; public PersonHandler(T target) { mTarget = target; } @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { // 调用开始前的操作 ProxyUtil.start(); // 调用方法,通过反射的形式来调用 mTarget 的 method Object result = method.invoke(mTarget, objects); // 打印改名前的名字 ProxyUtil.log(objects[0].toString()); // 调用结束后的操作 ProxyUtil.finish(); <

