java反射机制与动态代理

1 java反射机制:运行时的类信息 Class类与java.lang.reflect类库一起对反射概念进行了支持,该类库包含了Field,Method以及 Constructor类。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样就可以使用Constructor创建新的对象,用get()与set()方法读取与修改与Field对象相关的字段,用invoke()方法调用与Method对象相关的方法等等。 2 动态代理: 代理模式:为了提供额外的或不同的操作,而插入的用来代替“实际”对象。这些操作通常涉及与“实际”对象的通讯,因此代理通常充当着中间人的角色。 动态代理:所有的调用都会被重定向到单一的调用处理器上,他的工作是揭示调用的类型并确定相应的对策。 java反射机制实现动态代理的源码: Java代码 1. interface Interface { 2. void doSomething(); 3. void somethingElse(String arg); 4. } 5. 6. class RealObject implements Interface { 7. public void doSomething() { print("doSomething"); } 8. public void somethingElse(String arg) { 9. print("somethingElse " + arg); 10. } 11. } interface Interface { void doSomething(); void somethingElse(String arg); } class RealObject implements Interface { public void doSomething() { print("doSomething"); } public void somethingElse(String arg) { print("somethingElse " + arg); } } Java代码 1. import java.lang.reflect.*; 2. 3. class DynamicProxyHandler implements InvocationHandler { 4. private Object proxied; 5. 6. public DynamicProxyHandler(Object proxied) { 7. this.proxied = proxied; 8. } 9. 10. public Object invoke(Object proxy, Method method, Object[] args) 11. throws Throwable { 12. System.out.println("**** proxy: " + proxy.getClass() + ", method: " 13. + method + ", args: " + args); 14. if (args != null) 15. for (Object arg : args) 16. System.out.println(" " + arg); 17. return method.invoke(proxied, args); 18. } 19. } 20. 21. public class SimpleDynamicProxy { 22. public static void consumer(Interface iface) { 23. iface.doSomething(); 24. iface.somethingElse("bonobo"); 25. } 26. 27. public static void main(String[] args) { 28. RealObject real = new RealObject(); 29. consumer(real); 30. // Insert a proxy and call again: 31. Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class 32. .getClassLoader(), new Class[] { Interface.class }, 33. new DynamicProxyHandler(real)); 34. consumer(proxy); 35. } 36. } import java.lang.reflect.*; class DynamicProxyHandler implements InvocationHandler { private Object proxied; public DynamicProxyHandler(Object proxied) { this.proxied = proxied; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("**** proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args); if (args != null) for (Object arg : args) System.out.println(" " + arg); return method.invoke(proxied, args); } } public class SimpleDynamicProxy { public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse("bonobo"); } public static void main(String[] args) { RealObject real = new RealObject(); consumer(real); // Insert a proxy and call again: Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class .getClassLoader(), new Class[] { Interface.class }, new DynamicProxyHandler(real)); consumer(proxy); } } 当我们查看java.lang.reflect.Proxy源码,我们发现起核心作用的是 ProxyGenerator.generateProxyClass(String paramString, Class[] paramArrayOfClass),最令人疑惑的问题是,代理对象和如何调用DynamicProxyHandler的invoke方法的,从源码里面我们很难发现如何处理的,对于ProxyGenerator写了一个测试类ProxyClassFile Java代码 1. import java.io.File; 2. import java.io.FileNotFoundException; 3. import java.io.FileOutputStream; 4. import java.io.IOException; 5. 6. import sun.misc.ProxyGenerator; 7. 8. public class ProxyClassFile { 9. 10. public static void main(String[] args) { 11. 12. String proxyName = "SimpleDynamicProxy"; 13. 14. RealObject t = new RealObject(); 15. 16. Class[] interfaces = t.getClass().getInterfaces(); 17. 18. byte[] proxyClassFile = ProxyGenerator.generateProxyClass( 19. 20. proxyName, interfaces); 21. 22. File f = new File("E:/workspace/TIJ4/bin/typeinfo/SimpleDynamicProxy.class"); 23. 24. try { 25. 26. FileOutputStream fos = new FileOutputStream(f); 27. 28. fos.write(proxyClassFile); 29. 30. fos.flush(); 31. 32. fos.close(); 33. 34. } catch (FileNotFoundException e) { 35. 36. e.printStackTrace(); // To change body of catch statement use File | 37. // Settings | File Templates. 38. 39. } catch (IOException e) { 40. 41. e.printStackTrace(); // To change body of catch statement use File | 42. // Settings | File Templates. 43. 44. } 45. 46. } 47. 48. } import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import sun.misc.ProxyGenerator; public class ProxyClassFile { public static void main(String[] args) { String proxyName = "SimpleDynamicProxy"; RealObject t = new RealObject(); Class[] interfaces = t.getClass().getInterfaces(); byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces); File f = new File("E:/workspace/TIJ4/bin/typeinfo/SimpleDynamicProxy.class"); try { FileOutputStream fos = new FileOutputStream(f); fos.write(proxyClassFile); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); // To change body of catch statement use File | // Settings | File Templates. } catch (IOException e) { e.printStackTrace(); // To change body of catch statement use File | // Settings | File Templates. } } } 反编译SimpleDynamicProxy.class,代码初看起来有点复杂,仔细观察还是很有规律的,将 SimpleDynamicProxy5个方法都重定向到invoke()方法,equals(),hashCode()和toString()都是父类 Object方法,doSomething()和somethingElse()为接口方法。 Java代码 1. import java.lang.reflect.InvocationHandler; 2. import java.lang.reflect.Method; 3. import java.lang.reflect.Proxy; 4. import java.lang.reflect.UndeclaredThrowableException; 5. import typeinfo.Interface; 6. 7. public final class SimpleDynamicProxy extends Proxy 8. implements Interface 9. { 10. private static Method m1; 11. private static Method m0; 12. private static Method m3; 13. private static Method m4; 14. private static Method m2; 15. 16. public SimpleDynamicProxy(InvocationHandler paramInvocationHandler) 17. throws 18. { 19. super(paramInvocationHandler); 20. } 21. 22. public final boolean equals(Object paramObject) 23. throws 24. { 25. try 26. { 27. return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); 28. } 29. catch (RuntimeException localRuntimeException) 30. { 31. throw localRuntimeException; 32. } 33. catch (Throwable localThrowable) 34. { 35. throw new UndeclaredThrowableException(localThrowable); 36. } 37. } 38. 39. public final int hashCode() 40. throws 41. { 42. try 43. { 44. return ((Integer)this.h.invoke(this, m0, null)).intValue(); 45. } 46. catch (RuntimeException localRuntimeException) 47. { 48. throw localRuntimeException; 49. } 50. catch (Throwable localThrowable) 51. { 52. throw new UndeclaredThrowableException(localThrowable); 53. } 54. } 55. 56. public final void doSomething() 57. throws 58. { 59. try 60. { 61. this.h.invoke(this, m3, null); 62. return; 63. } 64. catch (RuntimeException localRuntimeException) 65. { 66. throw localRuntimeException; 67. } 68. catch (Throwable localThrowable) 69. { 70. throw new UndeclaredThrowableException(localThrowable); 71. } 72. } 73. 74. public final void somethingElse(String paramString) 75. throws 76. { 77. try 78. { 79. this.h.invoke(this, m4, new Object[] { paramString }); 80. return; 81. } 82. catch (RuntimeException localRuntimeException) 83. { 84. throw localRuntimeException; 85. } 86. catch (Throwable localThrowable) 87. { 88. throw new UndeclaredThrowableException(localThrowable); 89. } 90. } 91. 92. public final String toString() 93. throws 94. { 95. try 96. { 97. return (String)this.h.invoke(this, m2, null); 98. } 99. catch (RuntimeException localRuntimeException) 100. { 101. throw localRuntimeException; 102. } 103. catch (Throwable localThrowable) 104. { 105. throw new UndeclaredThrowableException(localThrowable); 106. } 107. } 108. 109. static 110. { 111. try 112. { 113. m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); 114. m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); 115. m3 = Class.forName("typeinfo.Interface").getMethod("doSomething", new Class[0]); 116. m4 = Class.forName("typeinfo.Interface").getMethod("somethingElse", new Class[] { Class.forName("java.lang.String") }); 117. m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); 118. return; 119. } 120. catch (NoSuchMethodException localNoSuchMethodException) 121. { 122. throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); 123. } 124. catch (ClassNotFoundException localClassNotFoundException) 125. { 126. throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); 127. } 128. } 129. } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import typeinfo.Interface; public final class SimpleDynamicProxy extends Proxy implements Interface { private static Method m1; private static Method m0; private static Method m3; private static Method m4; private static Method m2; public SimpleDynamicProxy(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { 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 hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void doSomething() throws { try { this.h.invoke(this, m3, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void somethingElse(String paramString) throws { try { this.h.invoke(this, m4, new Object[] { paramString }); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() throws { 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") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("typeinfo.Interface").getMethod("doSomething", new Class[0]); m4 = Class.forName("typeinfo.Interface").getMethod("somethingElse", new Class[] { Class.forName("java.lang.String") }); 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()); } } } 通过源代码我们不难看出,代理类是如何调用invoke方法的了。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值