您的位置:首页 > 其它

使用ProxyGenerator类生成字节码

2016-06-30 00:00 260 查看
摘要: Java的动态代理可以根据指定的接口动态的生成字节码并且加载,这篇文章就介绍一下Java Proxy代理类使用的ProxyGenerator生成的类是怎么样的。

首先,有一个实体类:

public class User {
private Integer id;

private String name;

private String address;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

然后是一个Mapper文件,下面这个接口是我使用MyBatise生成工具生成的Mapper文件:

import cn.freemethod.to.User;

public interface UserMapper {
int deleteByPrimaryKey(Integer id);

int insert(User record);

int insertSelective(User record);

User selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(User record);

int updateByPrimaryKey(User record);
}

使用一个主类来生成UserMapper接口的代理类:

import java.io.FileOutputStream;
import java.io.IOException;

import cn.freemethod.dao.mapper.ms.UserMapper;
import sun.misc.ProxyGenerator;

@SuppressWarnings("restriction")
public class ProxyGeneratorUtil {

private static String DEFAULT_CLASS_NAME = "$Proxy";

public static byte [] saveGenerateProxyClass(String path,Class<?> [] interfaces) {

byte[] classFile = ProxyGenerator.generateProxyClass(DEFAULT_CLASS_NAME, interfaces);

FileOutputStream out = null;

try {
String filePath = path + "/" + DEFAULT_CLASS_NAME + ".class";
out = new FileOutputStream(filePath);
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(out != null) out.close();
} catch (IOException e) {
//ignore
}
}
return classFile;
}

public static void main(String[] args) {

Class<?> interfaces [] = {UserMapper.class};
//运行时,确保目录存在
/*byte[] classFile = */saveGenerateProxyClass("f:/tmp", interfaces);

}

}

使用反编译工具,如JD-GUI把生成保存在磁盘的字节码文件反编译出来:

import cn.freemethod.dao.mapper.ms.UserMapper;
import cn.freemethod.to.User;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy extends Proxy
implements UserMapper
{
private static Method m3;
private static Method m1;
private static Method m8;
private static Method m4;
private static Method m7;
private static Method m5;
private static Method m0;
private static Method m6;
private static Method m2;

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

public final int insert(User paramUser)
throws
{
try
{
return ((Integer)this.h.invoke(this, m3, new Object[] { paramUser })).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int updateByPrimaryKey(User paramUser)
throws
{
try
{
return ((Integer)this.h.invoke(this, m8, new Object[] { paramUser })).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int deleteByPrimaryKey(Integer paramInteger)
throws
{
try
{
return ((Integer)this.h.invoke(this, m4, new Object[] { paramInteger })).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int updateByPrimaryKeySelective(User paramUser)
throws
{
try
{
return ((Integer)this.h.invoke(this, m7, new Object[] { paramUser })).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int insertSelective(User paramUser)
throws
{
try
{
return ((Integer)this.h.invoke(this, m5, new Object[] { paramUser })).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final User selectByPrimaryKey(Integer paramInteger)
throws
{
try
{
return (User)this.h.invoke(this, m6, new Object[] { paramInteger });
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

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

static
{
try
{
m3 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("insert", new Class[] { Class.forName("cn.freemethod.to.User") });
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m8 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("updateByPrimaryKey", new Class[] { Class.forName("cn.freemethod.to.User") });
m4 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("deleteByPrimaryKey", new Class[] { Class.forName("java.lang.Integer") });
m7 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("updateByPrimaryKeySelective", new Class[] { Class.forName("cn.freemethod.to.User") });
m5 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("insertSelective", new Class[] { Class.forName("cn.freemethod.to.User") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m6 = Class.forName("cn.freemethod.dao.mapper.ms.UserMapper").getMethod("selectByPrimaryKey", new Class[] { Class.forName("java.lang.Integer") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}

我们可以清楚的看到,生成的代理类是public final的继承了Proxy,实现了要代理的接口UserMapper。

每一个代理的方法都是final的,都是通过调用InvacationHandler的invoke方法来实现代理的。并且把自身和被代理的方法作为参数传递进去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息