首先,有一个实体类:
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方法来实现代理的。并且把自身和被代理的方法作为参数传递进去。