1. 程式人生 > >Java-Proxy是在什麽時候調用InvocationHandler的invoke方法的

Java-Proxy是在什麽時候調用InvocationHandler的invoke方法的

string 記錄 throws class noclass static courier stat net

最近看到spring的動態代理,扒到深處看到時 Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);看到這一句,頓時比較懵逼,還是沒有搞懂invoke方法的調用,然後搜索了一下,礙,遇見一位大神的文章

特來記錄一下,嘿嘿:首先這裏是原文鏈接

其實前面的可以省略了(太晚啦,要睡覺啦),什麽創建接口、實現類、創建實現InvocationHandler的類(不創建也行)等等操作,直接上重點,代理對象執行invoke的地方:

首先,我們編譯後,會得出一個代理對象的class文件,打開這個class文件就解開謎題了(當時也是懵逼了,這招沒想到,啊哈哈):

我們Proxy的類中,有一個受保護的InvocationHandler成員屬性:

public class Proxy implements java.io.Serializable {

    private static final long serialVersionUID = -2222568056686623797L;

    /** parameter types of a proxy class constructor */
    private static final Class<?>[] constructorParams =
        { InvocationHandler.
class }; /** * a cache of proxy classes */ private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory()); /** * the invocation handler for this proxy instance. *
@serial */ protected InvocationHandler h;//在這裏! /** * Prohibits instantiation. */ private Proxy() { } /** * Constructs a new {@code Proxy} instance from a subclass * (typically, a dynamic proxy class) with the specified value * for its invocation handler. * * @param h the invocation handler for this proxy instance * * @throws NullPointerException if the given invocation handler, {@code h}, * is {@code null}. */ protected Proxy(InvocationHandler h) { Objects.requireNonNull(h); this.h = h; }

接著看代理對象的實現:

public final class $Proxy0 extends Proxy implements Subject(目標類,被代理的類) {  
    private static Method m1;  
    private static Method m0;  
    private static Method m3;  
    private static Method m2;  
  
    static {  
        try {  
            m1 = Class.forName("java.lang.Object").getMethod("equals",  
                    new Class[] { Class.forName("java.lang.Object") });  
  
            m0 = Class.forName("java.lang.Object").getMethod("hashCode",  
                    new Class[0]);  
  
            m3 = Class.forName("***.RealSubject").getMethod("request",  //代理方法名稱
                    new Class[0]);  
  
            m2 = Class.forName("java.lang.Object").getMethod("toString",  
                    new Class[0]);  
  
        } catch (NoSuchMethodException nosuchmethodexception) {  
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());  
        } catch (ClassNotFoundException classnotfoundexception) {  
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());  
        }  
    } //static  
  
    public $Proxy0(InvocationHandler invocationhandler) {  
        super(invocationhandler);  
    }  
  
    @Override  
    public final boolean equals(Object obj) {  
        try {  
            return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    @Override  
    public final int hashCode() {  
        try {  
            return ((Integer) super.h.invoke(this, m0, null)).intValue();  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    public final void request() {  //代理方法
        try {  
            super.h.invoke(this, m3, null);  
            return;  
        } catch (Error e) {  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
  
    @Override  
    public final String toString() {  
        try {  
            return (String) super.h.invoke(this, m2, null);  
        } catch (Throwable throwable) {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  
}  

看到這裏就明白了。新返回的代理對象,調用了父類(Proxy)h的方法,這裏也就是invoke方法與Proxy相關的地方啦。

Java-Proxy是在什麽時候調用InvocationHandler的invoke方法的