博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解OSGi类加载机制
阅读量:7117 次
发布时间:2019-06-28

本文共 1182 字,大约阅读时间需要 3 分钟。

      OSGi之所以能够实现模块热插拔和模块内部可见性的精准控制都归结于其特殊的类加载机制.加载器之间的关系不再是双亲委派模型的树状结构,而是发展成复杂的网状结构。

       根据OSGi规范说明:

对于类或资源加载,框架必须遵循以下规则。 当请求bundle的类加载器加载类或资源时,必须按以下顺序执行搜索:

  1. 如果类或资源在java.*包中,则将请求委托给父类加载器; 否则,继续下一步搜索。 如果请求被委托给父类加载器还找不到类或资源,则搜索终止并且失败。
  2. 如果类或资源来自引导委派列表(系统变量org.osgi.framework.bootdelegation)中包含的包,则将请求委托给父类加载器。如果在那里找不到类或资源,继续下一步搜索。
  3. 如果类或资源属于声明在Import-Package导入的包中,或者是在先前的加载中动态导入的,那么请求将委托给声明Export-Package这个包的bundle的类加载器;否则继续下一步搜索。如果请求被委托给导出类加载器但找不到类或资源,则失败。
  4. 如果类或资源位于在多个Require-Bundle包中导入的包中,则请求将按照清单中指定的顺序委派给其他包的类加载器。这个过程中使用深度优先策略;如果未找到类或资源,则继续下一步搜索。
  5. 搜索bundle的内嵌jar的类路径(Bundle Class Path)。如果找不到类或资源,继续下一步。
  6. 查找Bundle的Fragment Bundle中导入的包, 如果没找到继续下一步
  7. 如果类或资源位于自己导出的包中,则搜索结束并失败。
  8. 否则,如果类或资源位于DynamicImport-Package导入的包中,则尝试动态导入包。
  9. 如果动态导入包成功,则将请求委托给导出这个包的类加载器。如果请求被委托给导出类加载器并且找不到类或资源,则搜索终止且失败。

总体图:  

     但这种模式也会产生许多隐患,比如循环依赖问题,如果BundleA依赖BundleB , BundleB依赖BundleC, BundleC又依赖BundleA, 这可能在加载Bundle的时候导致死锁问题。为了避免这种情况,根据OSGi规范说明,在这种情况下,框架必须在第一次访问Bundle的时候做标记,不去访问已经访问过的Bundle.

     另外,在OSGi中Bundle都有自己独有的ClassLoader, Fragment Bundle不同于普通Bundle, 其和其附着的Host Bundle共享一个ClassLoader.

如果在开发Liferay的过程中遇到Unresolved import-Package问题,可以参考我在Liferay的一篇博客

参考文献

  1. 深入理解Java虚拟机第三版(周志明)

 

转载于:https://juejin.im/post/5c67bd5a518825625c27168a

你可能感兴趣的文章
working with fitnesse wiki pages
查看>>
sql事务(Transaction)用法介绍及回滚实例
查看>>
根据二位数组的某个字段删除多余的一维数组
查看>>
16g u盘变 成1g u盘 解决方案,使用驱动器中的光盘之前需要将其格式化
查看>>
Mac 下更新 bash_profile文件
查看>>
Java初学——输出和输入处理
查看>>
LeetCode-Longest Substring Without Repeating Characters
查看>>
shell命令:sed命令
查看>>
Mysql相关函数使用和总结(cast、convert)
查看>>
Ruby设计模式-观察者模式学习笔记
查看>>
您需要售后返修管理软件的N个理由
查看>>
git 提交项目代码到码云步骤 以及出现错误解决办法
查看>>
线性表
查看>>
ceph
查看>>
如果Google面试让你用python写一个树的遍历程序
查看>>
Java第四次实验
查看>>
为discuz x2.5添加播放附件(mp4)的方法
查看>>
SpringMVC深度探险(一) —— SpringMVC前传
查看>>
面试 框架部分
查看>>
display: flex属性介绍
查看>>