对于Dynamic Proxy的原理,很多地方都有介绍,里面最神秘的就是JVM会在运行时动态生成一个类,好奇心驱使,想看看这个生成的类的代码是啥样的。于是,跟踪到Proxy.newProxyInstance()中,发现生成代码的关键语句byte[] ProxyGenerator.generateProxyClass(String proxyname,Class[] instances),写了段代码来输出那个类文件,并得到反编译的结果
----------IPerson .java-----------
package cn.edu.tju.bme;
public interface IPerson {
public void insertPerson();
public String getPersonName();
}
----------TestInvocationHandler.java-----------
package cn.edu.tju.bme;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TestInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
------------Main.java-----------
package cn.edu;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import sun.misc.ProxyGenerator;
import cn.edu.tju.bme.IPerson;
import cn.edu.tju.bme.TestInvocationHandler;
public class Main {
public static void main(String[] args) throws IOException {
String proxyName = "proxyName";
InvocationHandler handler = new TestInvocationHandler();
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, new Class[]{IPerson.class});
FileOutputStream fos = new FileOutputStream(new File("D:\\ProxyName.class"));
fos.write(proxyClassFile);
fos.flush();
fos.close();
}
}
---------------------------
反编译生成的ProxyName.class,得到的源文件如下:
----------proxyName.java-----------
import cn.edu.tju.bme.IPerson;
import java.lang.reflect.*;
public final class proxyName extends Proxy
implements IPerson
{
public proxyName(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
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);
}
}
public final String getPersonName ()
{
try
{
return (String)super.h.invoke(this, m4, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final void insertPerson ()
{
try
{
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
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);
}
}
private static Method m2;
private static Method m0;
private static Method m4;
private static Method m3;
private static Method m1;
static
{
try
{
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m4 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("getPersonName", new Class[0]);
m3 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("insertPerson", new Class[0]);
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
public String getPersonName();
}
----------TestInvocationHandler.java-----------
package cn.edu.tju.bme;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TestInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
------------Main.java-----------
package cn.edu;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import sun.misc.ProxyGenerator;
import cn.edu.tju.bme.IPerson;
import cn.edu.tju.bme.TestInvocationHandler;
public class Main {
public static void main(String[] args) throws IOException {
String proxyName = "proxyName";
InvocationHandler handler = new TestInvocationHandler();
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, new Class[]{IPerson.class});
FileOutputStream fos = new FileOutputStream(new File("D:\\ProxyName.class"));
fos.write(proxyClassFile);
fos.flush();
fos.close();
}
}
---------------------------
反编译生成的ProxyName.class,得到的源文件如下:
----------proxyName.java-----------
import cn.edu.tju.bme.IPerson;
import java.lang.reflect.*;
public final class proxyName extends Proxy
implements IPerson
{
public proxyName(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
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);
}
}
public final String getPersonName ()
{
try
{
return (String)super.h.invoke(this, m4, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final void insertPerson ()
{
try
{
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
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);
}
}
private static Method m2;
private static Method m0;
private static Method m4;
private static Method m3;
private static Method m1;
static
{
try
{
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m4 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("getPersonName", new Class[0]);
m3 = Class.forName("cn.edu.tju.bme.IPerson").getMethod("insertPerson", new Class[0]);
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}