java的动态代理到底生成了什么

java的动态代理到底生成了什么? 博客分类: java Java虚拟机JVMSUN java的动态代理到底生成了什么? http://yy629.iteye.com 344850459 日期: 2010-06-01 我们对java的动态代理机制可能都会使用, 但对于java生成动态生成接口的实现类可能不是很了解. 通过查看Proxy中的newProxyInstance方法, 发现最终都是由ProxyGenerator类来完成的, ProxyGenerator.generateProxyClass方法生成了实现类的字节码, 然后加载到虚拟机中的. 那生成的字节码是什么样子的? 我们可以将生成的字节码保存到文件中, 然后反编译就可以看到它的真面目了. Java代码 收藏代码 package demo; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Properties; /** * @author yeyong */ public class ProxyTest2 { public static void main(String[] args) throws Exception { // 添加以下的几段代码, 就可以将代理生成的字节码保存起来了 Field field = System.class.getDeclaredField("props"); field.setAccessible(true); Properties props = (Properties) field.get(null); props.put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); Package pkg = ProxyTest2.class.getPackage(); if (pkg != null) { String packagePath = pkg.getName().replace(".", File.pathSeparator); new File(packagePath).mkdirs(); } IA a = new IAImpl(); InvocationHandlerImpl ih = new InvocationHandlerImpl(a); IA proxyA = (IA) Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), ih); proxyA.a(); } } interface IA { void a(); int b(String str); } class IAImpl implements IA { @Override public void a() { System.out.println("IAImpl.a()"); } @Override public int b(String str) { System.out.println("IAImpl.b()"); return 0; } } class InvocationHandlerImpl implements InvocationHandler { private Object target; public InvocationHandlerImpl(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before..."); Object res = method.invoke(target, args); System.out.println("after..."); return res; } } 通过运行上面的代码, 我们就可以看到生成的类文件 $Proxy0.class 我们将其反编译一下, 得到它的java源码 Java代码 收藏代码 package demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements IA { private static Method m1; private static Method m4; private static Method m3; private static Method m0; private static Method m2; public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } public final boolean equals(Object paramObject) { try { return ((Boolean) this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int b(String paramString) { try { return ((Integer) this.h.invoke(this, m4, new Object[] { paramString })).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void a() { try { this.h.invoke(this, m3, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer) this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String) this.h.invoke(this, m2, null); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m4 = Class.forName("demo.IA").getMethod("b", new Class[] { Class.forName("java.lang.String") }); m3 = Class.forName("demo.IA").getMethod("a", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } } 动态生成的实现类中的所有方法都是调用了this.h.invoke方法(即InvocationHandler的接口方法). 看到此, 也明白了java动态代理的实现机制了. 通过Proxy.newProxyInstance`调用ProxyGenerator.generateProxyClass方法获得实现类的字节码数据, 然后加载到jvm中, 在调用构造函数, 生成实例. 这里是简化的过程, 其中还有一些权限检查,缓存和优化处理等, 对于如何生成class文件的, 可以看下ProxyGenerator的代码, 简单的说就是按照指定的格式写入字节码, 可以看出, 生成的实现类方法都是很有规律的

转载于:https://my.oschina.net/u/254456/blog/711660

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值