锁定老帖子 主题:java反射机制与动态代理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-02
最后修改:2010-06-03
1 java反射机制:运行时的类信息 Class类与java.lang.reflect类库一起对反射概念进行了支持,该类库包含了Field,Method以及Constructor类。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样就可以使用Constructor创建新的对象,用get()与set()方法读取与修改与Field对象相关的字段,用invoke()方法调用与Method对象相关的方法等等。
2 动态代理: 代理模式:为了提供额外的或不同的操作,而插入的用来代替“实际”对象。这些操作通常涉及与“实际”对象的通讯,因此代理通常充当着中间人的角色。 动态代理:所有的调用都会被重定向到单一的调用处理器上,他的工作是揭示调用的类型并确定相应的对策。 java反射机制实现动态代理的源码: 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); } }
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 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()为接口方法。 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方法的了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-03
xu547465458 写道 磁带存储\磁盘存储设备的,维保、销售、系统化服务商 www.storage81.com 专业从事磁带机、磁带库、磁盘阵列、信息化建设、存储系统的业务,全方位提供网络数据安全解决方案和系统集成服务。 作为一家具有较强综合实力的公司目前主要代理如下产品: HP公司磁带机、磁带库等存储系统增值代理; IBM公司磁带机、磁带库存储系统中国代理; Quantum公司存储产品最佳合作伙伴; Veritas、Bakbone、备份软件代理; EMC、SUN磁盘阵列产品专业代理; 网络视频监控服务器 专业磁盘存储厂商 Tel:021-62111580 62113278 Mobile:13636302561沪、13761648996、 Mail: info@storage81.com QQ:873372631 竟然有人在这里做广告,要怎么把它删掉 |
|
返回顶楼 | |
发表时间:2010-06-03
Arron.li 写道 xu547465458 写道 磁带存储\磁盘存储设备的,维保、销售、系统化服务商 www.storage81.com
专业从事磁带机、磁带库、磁盘阵列、信息化建设、存储系统的业务,全方位提供网络数据安全解决方案和系统集成服务。 作为一家具有较强综合实力的公司目前主要代理如下产品: HP公司磁带机、磁带库等存储系统增值代理; IBM公司磁带机、磁带库存储系统中国代理; Quantum公司存储产品最佳合作伙伴; Veritas、Bakbone、备份软件代理; EMC、SUN磁盘阵列产品专业代理; 网络视频监控服务器 专业磁盘存储厂商 Tel:021-62111580 62113278 Mobile:13636302561沪、13761648996、 Mail: info@storage81.com QQ:873372631 竟然有人在这里做广告,要怎么把它删掉 这个家伙到处乱贴,请管理员速度封其号。 |
|
返回顶楼 | |
发表时间:2010-06-03
网管不删广告,只会关我小黑屋,我已经不怕了
|
|
返回顶楼 | |
发表时间:2010-06-03
eye的管理员效率也不高啊~~~~
|
|
返回顶楼 | |
发表时间:2010-06-03
smzd 写道 网管不删广告,只会关我小黑屋,我已经不怕了
我也不怕了!! |
|
返回顶楼 | |
浏览 5925 次