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