使用ProxyGenerator类生成字节码

原创
2016/06/30 19:49
阅读数 5.5K

首先,有一个实体类:

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的,都是通过调用InvacationHandlerinvoke方法来实现代理的。并且把自身和被代理的方法作为参数传递进去。

展开阅读全文
打赏
0
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
0
分享
返回顶部
顶部