java 动态代理

2019-04-09  本文已影响0人  风吟空城

java动态代理主要是通过InvocationHandler接口和Proxy类结合实现。下面逐一解释下两者的用法。

InvocationHandler

InvocationHandler接口源码

/**
 * {@code InvocationHandler} is the interface implemented by
 * the <i>invocation handler</i> of a proxy instance.
 *
 * <p>Each proxy instance has an associated invocation handler.
 * When a method is invoked on a proxy instance, the method
 * invocation is encoded and dispatched to the {@code invoke}
 * method of its invocation handler.
 *
 * @author      Peter Jones
 * @see         Proxy
 * @since       1.3
 */
public interface InvocationHandler {

因为找不到合适的称呼,所以把invocation handler统一翻译为调用处理程序,作为名词使用。

代理类实例的调用处理程序都必须实现InvocationHandler接口,每个代理类实例中都有一个与之关联调用处理程序。当我们通过代理类实例调用一个方法的时候,这个方法调用就会被编码、转发到调用处理程序invoke方法。

Invoke方法

invoke源码:

    /**
     * Processes a method invocation on a proxy instance and returns
     * the result.  This method will be invoked on an invocation handler
     * when a method is invoked on a proxy instance that it is
     * associated with.
     *
     * @param   proxy the proxy instance that the method was invoked on
     *
     * @param   method the {@code Method} instance corresponding to
     * the interface method invoked on the proxy instance.  The declaring
     * class of the {@code Method} object will be the interface that
     * the method was declared in, which may be a superinterface of the
     * proxy interface that the proxy class inherits the method through.
     *
     * @param   args an array of objects containing the values of the
     * arguments passed in the method invocation on the proxy instance,
     * or {@code null} if interface method takes no arguments.
     * Arguments of primitive types are wrapped in instances of the
     * appropriate primitive wrapper class, such as
     * {@code java.lang.Integer} or {@code java.lang.Boolean}.
     */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

参数解释

Proxy

Proxy提供了很多静态方法来创建动态代理类和代理类实例,而且它还是所有它创建的动态代理类的超级父类。

/**
 * {@code Proxy} provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
 */
public class Proxy implements java.io.Serializable {

InvocationHandler结合使用时,主要使用的静态方法是newProxyInstance

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
throws IllegalArgumentException {
  ...
}

demo

接口代码

public interface People {

    /**
     * 晚餐吃什么
     * @return 食物
     */
    String dinner();
}

实现类

public class ItWorker implements People {

    @Override
    public String dinner() {
        return "KFC";
    }

}

调用处理程序

public class PeopleHandler implements InvocationHandler {

    private Object obj;

    PeopleHandler() {
    }

    PeopleHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(obj, args);
    }

}

PeopleHandler就是我们所说的调用处理程序,会在代理类创建代理实例时,作为参数(测试类中的peopleHandler)使用。通过demo可以更好的理解InvocationHandler的参数及功能。

测试类

public class PeopleTest {

    public static void main(String [] args){
        //真实对象
        People people = new ItWorker();
        //调用处理程序
        PeopleHandler peopleHandler = new PeopleHandler(people);
        //代理
        People proxy = (People) Proxy.newProxyInstance(peopleHandler.getClass().getClassLoader(),
                people.getClass().getInterfaces(), peopleHandler);
        System.out.println(proxy.dinner());
    }

}
上一篇下一篇

猜你喜欢

热点阅读