类加载器特技:OSGi代码生成
2010-03-01 00:00:00 来源:WEB开发网增强类扩充了应用代码 - 应用可以直接调用生成的对象。例如,一个传递给应用代码的服务代理对象就是这种增强类对象,它使得应用代码不必去跟踪一个动态服务。简单的说,增加了一些AOP特征的包装器被作为原始对象的替代品传递给应用代码。
增强类的生命始于字节数组byte[],由你喜爱的类工程库(ASM,BCEL,CGLIB)产生。一旦我们生成了我们的类,必须把这些原始的字节转换为一个Class对象,换言之,我们必须让某个类加载器对我们的字节调用它的defineClass()方法。我们有三个独立的问题要解决:
类空间完整性 - 首先我们必须决定可以定义我们增强类的类空间。该类空间必须“看到”足够多的类以便让增强类能够被完全链接。
可见性 - ClassLoader.defineClass()是一个受保护的方法。我们必须找到一个好方法来调用它。
类空间一致性 - 增强类从框架和应用bundle混入类,这种加载类的方式对于OSGi容器来说是“不可见的”。作为结果,增强类可能被暴露给相同类的不兼容的版本。
类空间完整性
增强类的背后支持代码对于生成它们的Java框架来说是未公开的 - 这意味着该框架应该会把该新类加入到其类空间。另一方面,增强类实现的接口或者扩展的类在应用的类空间是可见,这意味着我们应该在这里定义增强类。我们不能同时在两个类空间定义一个类,所以我们有个麻烦。
因为没有类空间能够看到所有需要的类,我们别无选择,只能创建一个新的类空间。一个类空间等同于一个类加载器实例,所以我们的第一个工作就是在所有的应用bundle之上维持一个专有的类加载器。这些叫做桥接类加载器,因为他们通过链接加载器合并了两个类空间:
public class BridgeClassLoader extends ClassLoader {
private final ClassLoader secondary;
public BridgeClassLoader(ClassLoader primary, ClassLoader secondary) {
super(primary);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return secondary.loadClass(name);
}
}
赞助商链接