8.2 J2SE动态代理

    上节介绍了代理模式,我们创建了静态代理[1]Service_Stub类,其实Java还可以支持在运行时创建代理类,即所谓的动态代理。

    8.2.1 类和接口

    Java自从1.3版本开始,就引入了动态代理。在介绍如何使用之前,我们首先讲述一些相关的类和接口。

    1.Proxy类

    Proxy类提供了用于创建动态代理类和实例的静态方法,并且,它是你所创建的所有动态代理类的父类。我们看看这个类的两个主要方法。

    返回代理类的java.lang.Class对象,需要提供类加载器和指定代理的接口数组作为参数,如下所示。

    public static Class<?>getProxyClass(ClassLoader loader, Class<?>……interfaces)

    返回代理对象,需要指定类加载器,指定需要代理的接口数组和InvocationHandler对象作为参数,如下所示。

    public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h)

    其实这个方法逻辑相当于下面这句。

    figure_0137_0135

    2.InvocationHandler接口

    InvocationHandler对象集中控制所有代理的方法,这个接口只有一个方法需要实现。

    public Object invoke(Object proxy, Method method, Object[]args)throws Throwable

    其中:

    第一个参数proxy是代理类的实例;

    第二个参数method是调用代理实例的Method方法实例;

    第三个参数args是调用代理实例的接口方法时所传递的参数数组,如果调用的方法无参数,则传递值为null,如果是基本类型(Primitive)的参数,会被转化为相应基本包装器类的实例(例如int变量,会转化为一个Integer对象)。

    生成的动态代理会首先把请求统一转发给InvocationHandler对象的invoke()方法,如果想要直接调用目标对象target的相应方法,则代码如下所示。

    figure_0138_0136

    [1]相对于动态代理而言,即在编译期就就产生了class文件,这样就决定了运行时的功能。