类加载器特技:OSGi代码生成 - 编程入门网
要被连接类的所有引用类的完整的描述。它只需 要被链接类真正使用的个别的方法、字段和类型的信息。我们直觉上认为对于 JVM来说,其全部是一个类名称,加上一个超类,加上一套实现的接口,加上一 套方法签名,加上一套字段签名。所有这些符号是被独立且延迟解析的。例如, 要链接一个方法调用,调用者的类空间只需要给类对象提供目标类和方法签名中 用到的所有类型。目标类中的其他许多定义是不需要的,调用者的类加载器永远 不会收到加载它们(那些不需要的定义)的请求。
正式的答案: 类空间SpaceA的类A必须被类空间SpaceB的相同类对象所代表,当且仅当: SpaceB存在一个类B,在它的符号表(也叫做常量池)中引用着A。 OSGi容器已经将SpaceA作为类A的提供者(provider)提供给SpaceB。该联系 是建立在容器所有bundle的静态元数据之上的。 例如: 假设我们有一个bundle BndA导出一个类A。类A有3个方法,分布于3个接口中 : IX.methodX(String) IY.methodY(String) IZ.methodZ(String) 类加载器特技:OSGi代码生成(4)时间:2011-06-11 infoq 译:曹云飞还假设我们有一个bundle BndB,其有一个类B。类B中有一个引用 A a = … …和一个方法调用a.methodY("Hello!")。为了能够解析类B,我们需要为BndB的 类空间引入类A和类String。这就够了!我们不需要导入IX或者IZ。我们甚至不 需要导入IY,因为类B没有用IY - 它只用了A。在另一方面,bundle BndA导出时 会解析类A,必须提供IX,IY,IZ,因为他们作为被实现的接口直接被引用。最 终,BndA也不需要提供IX,IY,IZ的任何父接口,因为他们也没有被直接引用。 现在假设我们希望给类空间BndB的类B呈现类空间BndA的类A的一个增强版本 。该增强类需要继承类A并覆盖它的一些或全部方法。因此,该增强类需要看到 在所有覆盖的方法签名中使用的类。然而,BndB仅当调用了所有被覆盖的方法时 才会导入所有这些类。BndB恰好调用了我们的增强覆盖的所有的A 的方法的可能 性非常小。因此,BndB很可能在他的类空间中不会看到足够的类来定义增强类。 实际上完整的类集合只有BndA能够提供。我们有麻烦了! 结果是我们必须桥接的不是框架和应用空间,而是框架空间和增强类的空间 - 所以,我们必须把策略从“每个应用空间一个桥”变为“每个增强类空间一个 桥”。我们需要从应用空间到一些第三方bundle的类空间做过渡跳接,在那里, 应用导入其想让我们增强的类。但是我们如何做过渡跳接呢?很简单!如我们所 知,每个类对象可以告诉我们它第一次被定义的类空间是什么。例如,我们要得 到A 的类加载器,所需要做的就是调用A.class.getClassLoader()。在很多情况 下我们没有一个类对象,只有类的名字,那么我们如何从一开始就得到A.class ?也很简单!我们可以让应用bundle给我们它所看到的名称“A”对应的类对象 。然后我们就可以桥接那个类的空间与框架的空间。这是很关键的一步,因为我 们需要增强类和原始类在应用内是可以互换的。在类A可能的许多版本中,我们 需要挑选被应用所使用的那个类的类空间。下面是框架如何保持类加载器桥缓存 的示意性例子:
桥缓 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |