PS:这个结果的信息非常重要,至少对我来说。因为我在动态代理犯晕的根源就在于将上面的subject.request()理解错了,至少是被表面所迷惑,没有发现这个subject和Proxy之间的联系,一度纠结于最后调用的这个request()是怎么和invoke()联系上的,而invoke又是怎么知道request存在的。其实上面的true和class $Proxy0就能解决很多的疑问,再加上下面将要说的$Proxy0的源码,完全可以解决动态代理的疑惑了。
从以上代码和结果可以看出,我们并没有显示的调用invoke()方法,但是这个方法确实执行了。下面就整个的过程进行分析一下:
从Client中的代码看,可以从newProxyInstance这个方法作为突破口,我们先来看一下Proxy类中newProxyInstance方法的源代码:
Java代码
- public static Object newProxyInstance(ClassLoader loader,
- Class [] interfaces,
- InvocationHandler h)
- throws IllegalArgumentException
- {
- if (h == null) {
- throw new NullPointerException();
- }
- /*
- * Look up or generate the designated proxy class.
- */
- Class cl = getProxyClass(loader, interfaces);
- /*
- * Invoke its constructor with the designated invocation handler.
- */
- try {
- /*
- * Proxy源码开始有这样的定义:
- * private final static Class[] constructorParams = { InvocationHandler.class };
- * cons即是形参为InvocationHandler类型的构造方法
- */
- Constructor cons = cl.getConstructor(constructorParams);
- return (Object) cons.newInstance(new Object[] { h });
- } catch (NoSuchMethodException e) {
- throw new InternalError(e.toString());
- } catch (IllegalAccessException e) {
- throw new InternalError(e.toString());
- } catch (InstantiationException e) {
- throw new InternalError(e.toString());
- } catch (InvocationTargetException e) {
- throw new InternalError(e.toString());
- }
- }
Proxy.newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy0.$Proxy0类 实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把DynamicSubject传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
Java代码
- class Proxy{
- InvocationHandler h=null;
- protected Proxy(InvocationHandler h) {
- this.h = h;
- }
- ...
- }
来看一下这个继承了Proxy的$Proxy0的源代码:
Java代码
- 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;
- }