WEB开发网
开发学院软件开发Java 类加载器特技:OSGi代码生成 阅读

类加载器特技:OSGi代码生成

 2010-03-01 00:00:00 来源:WEB开发网   
核心提示: 正式的答案:类空间SpaceA的类A必须被类空间SpaceB的相同类对象所代表,当且仅当:SpaceB存在一个类B,类加载器特技:OSGi代码生成(5),在它的符号表(也叫做常量池)中引用着A,OSGi容器已经将SpaceA作为类A的提供者(provider)提供给SpaceB,因为我们需要增强

正式的答案:

类空间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)

还假设我们有一个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可能的许多版本中,我们需要挑选被应用所使用的那个类的类空间。下面是框架如何保持类加载器桥缓存的示意性例子:

上一页  1 2 3 4 5 6 7 8 9 10  下一页

Tags:加载 特技 OSGi

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接