快速业务通道

Java动态代理机制分析及扩展,第1部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-16
{    // 检查 h 不为空,否则抛异常    if (h == null) {      throw new NullPointerException();    }    // 获得与制定类装载器和一组接口相关的代理类类型对象    Class cl = getProxyClass(loader, interfaces);    // 通过反射获取构造函数对象并生成代理类实例    try {      Constructor cons = cl.getConstructor (constructorParams);      return (Object) cons.newInstance(new Object[] { h  });    } catch (NoSuchMethodException e) { throw new  InternalError(e.toString());    } catch (IllegalAccessException e) { throw new  InternalError(e.toString());    } catch (InstantiationException e) { throw new  InternalError(e.toString());    } catch (InvocationTargetException e) { throw new  InternalError(e.toString());    } }

由此可见,动态代理真正的关键是在 getProxyClass 方法,该方法负责为一 组接口动态地生成代理类类型对象。在该方法内部,您将能看到 Proxy 内的各 路英雄(静态变量)悉数登场。有点迫不及待了么?那就让我们一起走进 Proxy 最最神秘的殿堂去欣赏一番吧。该方法总共可以分为四个步骤:

对这组接口进行一定程度的安全检查,包括检查接口类对象是否对类装载器 可见并且与类装载器所能识别的接口类对象是完全相同的,还会检查确保是 interface 类型而不是 class 类型。这个步骤通过一个循环来完成,检查通过 后将会得到一个包含所有接口名称的字符串数组,记为 String[] interfaceNames。总体上这部分实现比较直观,所以略去大部分代码,仅保留留 如何判断某类或接口是否对特定类装载器可见的相关代码。

清单 8. 通过 Class.forName 方法判接口的可见性

try {    // 指定接口名字、类装载器对象,同时制定 initializeBoolean  为 false 表示无须初始化类    // 如果方法返回正常这表示可见,否则会抛出  ClassNotFoundException 异常表示不可见    interfaceClass = Class.forName(interfaceName, false,  loader); } catch (ClassNotFoundException e) { } 

Java动态代理机制分析及扩展,第1部分(5)

时间:2011-06-21 IBM / 王忠平 何平

从 loaderToCache 映射表中获取以类装载器对象为关键字所对应的缓存表, 如果不存在就创建一个新的缓存表并更新到 loaderToCache。缓存表是一个 HashMap 实例,正常情况下它将存放键值对(接口名字列表,动态生成的代理类 的类对象引用)。当代理类正在被创建时它会临时保存(接口名字列表, pendingGenerationMarker)。标记 pendingGenerationMarke 的作用是通知后 续的同类请求(接口数组相同且组内接口排列顺序也相同)代理类正在被创建, 请保持等待直至创建完成。

清单 9. 缓存表的使用

do {    // 以接口名字列表作为关键字获得对应 cache 值    Object value = cache.get(key);    if (value instanceof Reference) {      proxyClass = (Class) ((Reference) value).get();    }    if (proxyClass != null) {      // 如果已经创建,直接返回      return proxyClass;    } else if (value == pendingGenerationMarker) {      // 代理类正在被创建,保持等待      try {        cache.wait();      } catch (InterruptedException e) {      }      // 等待被唤醒,继续循环并通过二次检查以确保创建完成,否则 重新等待      continue;    } else {      // 标记代理类正在

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号