Proxy Pattern

Proxy, 代理模式。是一种对象结构模式。按照 GoF 的定义,它是为其他对象提供一种代理以控制这个对象的访问。
具体实现中,不直接使用目标,而是通过代理间接使用。代理实现和被代理类同样的接口,让 client 能够和使用被代理类一样使用代理类。
proxy pattern

这里的图和维基百科《代理模式》词条用的略有不同,但含义是一致的。以上图示部分代码如下:
Subject
public interface Subject {
        void doAction();
}

RealSubject
public class RealSubject implements Subject {

        @Override
        public void doAction() {
              System.out.println("Hello from realSubject.doAction()!" );
       }

}

Proxy
public class Proxy implements Subject {

        @Override
        public void doAction() {
              System. out.println("before proxy" );
               new RealSubject().doAction();
              System. out.println("after proxy" );
       }

}

这些代码可以在这里下载。

以上例子中被代理的接口方法只有一个,如果 Subject 接口中有 n 个方法需要代理,就需要写 n 个,n 大了之后就比较麻烦,于是有了动态代理的需求,允许程序在运行时刻动态地创建代理类和对象。Java 中可以通过反射机制提供动态代理,这个功能是在 JDK 5 引入的。
动态代理的部分示例代码如下:
DynProxy
public class DynProxy implements InvocationHandler {

        private Object tar ;

        public Object bind(Object tar) {
               this .tar = tar;
               return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar
                           .getClass().getInterfaces(), this );
       }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                      throws Throwable {
              System. out.println("before proxy" );
              Object result = null ;
               // 这里就可以进行所谓的AOP编程了
               // 在调用具体函数方法前,执行功能处理
              result = method.invoke( tar , args);
               // 在调用具体函数方法后,执行功能处理
              System. out.println("after proxy" );
               return result;
       }

}

调用方式 Client
public class Client {

        public static void main(String[] args) {
              DynProxy proxy = new DynProxy();
               //绑定该类实现的所有接口
        Subject sub = (Subject) proxy.bind( new RealSubject());
        sub.doAction();
       }

}

动态代理完整的代码可在这里下载。


参考:
  1. 《知乎:动态代理的作用是什么》http://www.zhihu.com/question/20794107
  2. 《Java 深度历险(七)——Java 反射与动态代理》 http://www.infoq.com/cn/articles/cf-java-reflection-dynamic-proxy 

Comments