jdk动态代理参数理解

来源:互联网 发布:知无涯者百度云资源 编辑:程序博客网 时间:2024/05/20 17:59

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

  // 这里是生成class的地方  

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

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

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方法

1 0
原创粉丝点击