JDK DynamicProxy

153 阅读1分钟

##jdk 生成代理对象的代码

Proxy {
    //the invocation handler for this proxy instance.
    //猜测在newProxyInstance时,会将InvocationHandler赋给 h 
    protected InvocationHandler h;
    
    public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h){
                                            
    }
                                              
}

##那动态代理的代理类和代理对象是怎么产生的呢? ##下面我们看一下生成的代理类反编译后的内容:

import ProxyDemo.Base;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
//$Proxy0是生成代理的格式决定的
final class $Proxy0 extends Proxy implements Base {
	//为基础的tostring,equils,hashcode,还有base接口的方法生成method的对象
    private static Method m1;  //-->equals
    private static Method m2;  //-->toString
    private static Method m3;
    private static Method m4;  //-->hello
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }
	
	public final void hello(String var1) throws  {
        try {
            //this 即h,也就是所谓代理对象
            //m4 即为 hello 对应的 Method
            //new Object[]{var1} 是调用hello方法的参数列表
            super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void out() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    //具体的实现
    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("ProxyDemo$Base").getMethod("hello", Class.forName("java.lang.String"));
            m3 = Class.forName("ProxyDemo$Base").getMethod("out");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

首先从类的继承关系就很容易理解 Proxy.newProxyInstance(originalObj.getClass().getClassLoader(),originalObj.getClass().getInterfaces(), this);方法的作用了.

即继承了proxy类也实现了Base接口.这也是Base hello = (Base) new DynamicProxy().bind(new LoginImpl());这也是为什么可以强转为 Base对象的原因.同时在代理中将object类中的equils,tostring,hashcode以及所有base接口的方法生成对应的代理方法.

以hello方法为例介绍一下,h表示的是proxy类中的InvocationHandler,其实也就是指代我们之前的DynamicProxy对象,然后调用invoke方法就回到 DynamicProxy的invoke方法.我们就可以再次做很多中间的操作。