1)打断点,可以发现实际会生成新的对象去调用findLove。 把文件序列化到E盘
2)使用JAD把class文件反编译出来
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
import com.gupaoedu.vip.pattern.proxy.Person;
import java.lang.reflect.*;
public final class $Proxy0 extends Proxy
implements Person
{
public $Proxy0(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
public final boolean equals(Object obj)
{
try
{
return ((Boolean)super.h.invoke(this, m1, new Object[] {
obj
})).booleanValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final void findLove()
{
try
{
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString()
{
try
{
return (String)super.h.invoke(this, m2, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode()
{
try
{
return ((Integer)super.h.invoke(this, m0, null)).intValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
m3 = Class.forName("com.gupaoedu.vip.pattern.proxy.Person").getMethod("findLove", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
}
可以看出来,这个动态生成的类调用了super.h的invoke方法,并且传递过去3个参数:代理对象 方法 和参数
其中方法都是由于Girl继承Person接口被扫描出来的方法
理解JDK动态代理的实现原理:
1.拿到被代理类的引用,并且获取它的所有的接口(反射获取)。
2.JDK Proxy类要重新生成一个新的类,实现了被代理类所有接口中的方法
3.动态生成Java代码,把我们增强的逻辑加入到新生成的代码中。
4.编译生成新的Java代码的Class文件
5.加载并重新运行新的Class,得到的类就是全新的类。