jdk动态代理参数理解

    xiaoxiao2021-12-14  21

    使用jdk的动态代理非常简单,主要是在创建动态代理类的时候,传入三个参数Proxy.newProxyInstance(loader, interfaces, h);我们不仅要知道要传这个参数,还要知道为什么要传入这三个参数,第一个和第二个是类加载器和被代理对象实现的所有接口,在生成代理对象之前,会先判断缓存中是否存在代理对象,如果存在就直接返回。判断缓存中是否存在代理对象的时候就会用到类加载器(loader)和接口(interfaces),如果缓存中没有代理对象,就会生成一个代理对象,这个代理对象会继承Proxy类并且会实现被被代理对象所实现的所有接口。这个代理类还会有一个只有InvocationHandler类的构造函数。newProxyInstance内部就是根据反射找到代理类的构造函数,然后把InvocationHandler这个类掺入代理类中,然后利用反射再次生成代理类对象,这样就完成了。下面就贴出关键代码:

      // 这里是生成class的地方  

        Class<?> cl = getProxyClass0(loader, intfs);       // 使用我们实现的InvocationHandler作为参数调用构造方法来获得代理类的实例       try {           final Constructor<?> cons = cl.getConstructor(constructorParams);           final InvocationHandler ih = h;  //这就是调用构造函数生成动态代理类             return cons.newInstance(ih);      } catch (NoSuchMethodException e) {           throw new InternalError(e.toString());       }  

    接下来在看一下生成的代理类对象

    public final class $Proxy1 extends Proxy   implements Dog

    {

    public $Proxy1(InvocationHandler paramInvocationHandler)     throws    {     super(paramInvocationHandler);   }

    }

    很明显看出这个类继承了Proxy类和实现了Dog接口并且有一个只有一个参数的构造函数。这个代理会实现Dog接口中的所有方法,

    public final void eat()     throws    {     try     {       this.h.invoke(this, m4, null);       return;     }     catch (Error|RuntimeException localError)     {       throw localError;     }     catch (Throwable localThrowable)     {       throw new UndeclaredThrowableException(localThrowable);     }   }

    当调用代理类的eat方法时,实际上执行的是InvovcationHandler的invoke方法

    转载请注明原文地址: https://ju.6miu.com/read-968428.html

    最新回复(0)