使用ProxyGenerator类生成字节码
2016-06-30 00:00
260 查看
摘要: Java的动态代理可以根据指定的接口动态的生成字节码并且加载,这篇文章就介绍一下Java Proxy代理类使用的ProxyGenerator生成的类是怎么样的。
首先,有一个实体类:
然后是一个Mapper文件,下面这个接口是我使用MyBatise生成工具生成的Mapper文件:
使用一个主类来生成UserMapper接口的代理类:
使用反编译工具,如JD-GUI把生成保存在磁盘的字节码文件反编译出来:
我们可以清楚的看到,生成的代理类是public final的继承了Proxy,实现了要代理的接口UserMapper。
每一个代理的方法都是final的,都是通过调用InvacationHandler的invoke方法来实现代理的。并且把自身和被代理的方法作为参数传递进去。
首先,有一个实体类:
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方法来实现代理的。并且把自身和被代理的方法作为参数传递进去。
相关文章推荐
- JDK动态代理VS CgLib
- Spring AOP动态代理-切面
- MySQL Proxy(解决注入的另一思路)
- 动态代理的5模式使用示例和Mixin模式
- 详解java中动态代理实现机制
- mysql proxy问题的解决方法
- java实现动态代理示例分享
- java使用动态代理来实现AOP(日志记录)的实例代码
- java利用反射实现动态代理示例
- Win2003 WinHTTP Web Proxy Auto-Discovery Service 导致的服务器重启
- Java实现动态代理
- 十分钟理解Java中的动态代理
- java动态代理和cglib动态代理示例分享
- use jscript with List Proxy Server Information
- MySQL Proxy的安装及基本命令使用教程
- Ubuntu10下如何搭建MySQL Proxy读写分离探讨
- node-http-proxy修改响应结果实例代码
- WinHTTP Web Proxy Auto-Discovery Service 服务处于停止状态
- 实例解析jQuery中proxy()函数的用法