深入JVM OSGI-灵活的类加载架构

OSGI(Open Service Gateway Initiative)是一个由OSGI联盟联合制定的一个基于Java语言的动态模块化规范,而后这个规范得到不断发展,并具备成熟的特性,最著名的应用案例就是: Eclipse IDE 另外许多大型软件平台和服务器都是基于OSGI规范来实现的。

OSGI中的每个模块(Bundle)与普通的Java类库区别不大,2者都是由JAP格式封装,并且内部存储的都是Java Package和Class。但一个Bundle可以声明它所依赖的Java Package(通过Import Package描述),也可以声明它所允许的导出的Java Package(由Export-Package描述)

在OSGI里面,Bundle之间的依赖关系从传统的上层模块依赖下层模块转变为 平级模块之间的依赖 ,而且类库的可见性得到严格的控制,一个模块里只有被Export的Package才能被外界访问,其它的Package和Class会被隐藏起来。引入OSGI的另一个理由,可能实现热插拔功能,当程序升级时,只需要重新启动其中一小部分

OSGI之所以有如此优势,主要归功于它灵活的类加载架构。即Bundle类加载器之间只有规则,没有固定的委派原则。如,一个Bundle声明了一个它依赖的Package,如果其它的Bundle声明发布了这个Package,那么对这个Package类加载请求提交给发布过它的Bundle类加载器去完成。

一个例子:

BundleA: 声明发布了PackageA ,依赖java.*包

BundleB: 声明依赖了PackageA PackageC 同时也依赖java.*包

BundleC: 声明发布了PackageC 依赖PackageA

相应的类加载关系:

  • 以java.*开头的类,委派给父类加载器完成
  • 否则,委派给列表单内的类,委派给父类加载器完成
  • 否则,Import列表中的类,委派给Export这个类的Bundle类加载完成
  • 否则,查找当前Bundle的Classpath 使用自己的类加载器加载

从此可见,OSGI类加载架构不再是简单的双亲委派的模型,而是更为复杂的,运行期间确定的网状结构,这种架构提供了很强的灵活性,但同时也存在一定的安全隐患,容易发生复杂死锁,内存泄漏等问题

  •  

猜你喜欢

转载自blog.csdn.net/qq_33369979/article/details/88076049