最近开始投入时间,进行OSGI的学习,买了林昊的《OSGI的原理与实践》,并且参考51cto上的文章等其他资料,来整理知识
OSGI的动态模块性开发,很大程度在于OSGI中Bundle之间依赖性的设计方案,我个人认为这是OSGI 中一个很有价值的地方,
在我们平时的web开发中,虽然说是模块性开发,但是那种依赖设计,不是真正的模块,达不到即插即用,及删及无得效果;
而在OSGI规范中,则可以实现这种“理想中”的模块化,达到了,物理上脱离的模块开发。
回到Bundle之间依赖性的问题上来,
bundle之间类的共享:
通过 export package的方式实现的,在bundle的manifest中通过制定export package的方式将特定的package与其他的bundle共享。
而引用其他bundle所暴露的package有两种方式,第一是通过 import package的方式,第二种是通过required bundle的方式
OSGi容器为每个Bundle创建不同的classloader,
因此每个Bundle能访问位于下列位置中的类:
a) 位于Java启动类路径下的、所有以Java.*开头的包中的类;
b) 位于OSGi框架类路径下的类,通常有一个独立的类加载器负责加载框架的实现类及关键的接口类;
c) 位于Bundle空间中的类,这些类通常包含在与Bundle相关的jar文件中,以及加到这个Bundle中的其它jar包中的类。
d) 导入包中的类
当然整个OSGI容器,不能仅仅为每个Bundle创建各自的类加载器来达到对Bundle的管理,OSGI还提供了,parent classloader,和系统的classloader来进行管理。
整个的类的加载机制为:
1:如果package 为java。*则交由parent classloader
2:如果是boot delegates所定义的package 也交由parent classloader加载
3:如果是import package中所指定的,则由该package所在的bundle的类加载器加载
4:如果是required bundle的bundle中所export的package则由该bundle的classloader加载
5:在bundle本身的classpath中查找
6:如果是fragmentbundle中的package由本bundle的classloader加载(fragment bundle本身没有classloader)
7:dynamic import的package(与import package 的加载机制类似,只是时间点不同dynamic import只有在真正用到此package的时候才进行加载)
同时在export package的同时可以增加版本、自定义元数据等方式的限制,在import package时可以按照这些元数据进行更加精确地匹配。