支持模块化的动态部署
基于 OSGi 而构建的系统可以以模块化的方式(例如 jar 文件等)动态地部署至框架中,从而增加、扩展或改变系统的功能。要以模块化的方式部署到 OSGi 中,必须遵循 OSGi 的规范要求,那就是将工程创建为符合规范的 Bundle 工程(就是 Eclipse 中的插件工程),或者使用工具将工程打包成符合规范的 Jar 文件。
支持模块化的封装和交互
OSGi 支持模块化的部署,因此可以将系统按照模块或其他方式划分为不同的 Java 工程,这和以往做 Java 系统时逻辑上的模块化是有很大不同的,这样做就使得模块从物理级别上隔离了,也就不可能从这个模块直接调用另外模块的接口或类了。根据 OSGi 规范,每个工程可通过声明Export-Package 对外提供访问此工程中的类和接口, 也可通过将要对外提供的功能声明为 OSGi 的服务实现面向接口、面向服务式的设计。
基于 OSGi 的 Event 服务也是实现模块交互的一种可选方法,模块对外发布事件,订阅了此事件的模块就会相应地接收到消息,从而做出处理。
支持模块的动态配置
OSGi 通过提供 Configuration Admin 服务来实现模块的动态配置和统一管理,基于此服务各模块的配置可在运行期间进行增加、修改和删除,所有对于模块配置的管理统一调用 Configuration Admin 服务接口来实现。
支持模块的动态扩展
基于 OSGi 提供的面向服务的组件模型的设计方法,以及 OSGi 实现框架提供的扩展点方法可实现模块的动态扩展。那么,要使用 OSGi 框架提供的这些基本功能,在设计系统时就要遵循 OSGi 框架的设计思想。
模块化的设计
模块化的设计已经是大家在做系统设计时遵循的基本设计原则,但只有基于 OSGi 来做模块化的时候才会真正体验到何谓模块化,因为 OSGi 中的模块化是物理隔离的,而不基于 OSGi 的话很难做到物理隔离方式的模块化实现,也就很难使系统真正做到模块化,通常切换到基于 OSGi 后就会发现以前的模块化设计做得还是很不足。
基于 OSGi 进行模块化设计和传统的模块设计并没有多大的差别,均为定义模块的范围、模块对外提供的服务和所依赖的服务,相信大家在这点上很容易适应,在 OSGi 中只是更为规范,更为遵循面向服务的设计思想。
在 OSGi 中模块由一个或多个 Bundle 构成,模块之间的交互通过 Import-Package、Export-Package及 OSGi Service的方式实现。
面向服务的组件模型的设计
面向服务的组件模型(Service-Oriented Component Model)的设计思想是 OSGi 的核心设计思想, OSGi 推崇系统采用 Bundle 的方式来划分, Bundle 由多个 Component (组件) 来实现, Component通过对外提供服务接口和引用其他 Bundle 的服务接口来实现 Component 间的交互。
从这个核心的设计思想上可以看出,基于 OSGi 实现的系统自然就是符合 SOA 体系架构的。在 OSGi 中 Component 以 POJO 的方式编写,通过 DI 的方式注入其所引用的服务,以一个标准格式的 XML 描述 Component 引用服务的方式、对外提供的服务及服务的属性。
动态化的设计
动态化的设计是指系统中所有的模块均须支持动态的插拔和修改, 系统的模块要遵循对具体实现的零依赖和配置的统一维护(基于 Configuration Admin 服务) ,在设计时要记住的是所依赖的 OSGi服务或 Bundle 都是有可能动态卸载或安装的。对于模块的动态插拔和修改,OSGi 框架本身提供了支持,模块可通过 OSGi 的 Console(命令行 Console、Web console 等)安装、更新、卸载、启动、停止相应的 Bundle。
为保持系统的动态性,在设计时要遵循的原则是不要静态化地依赖任何服务,避免服务不可用时
造成系统的崩溃,从而保证系统的“即插即用,即删即无” 。
可扩展的设计
OSGi 在设计时提倡采用可扩展式的设计,即可通过系统中预设的扩展点来扩充系统的功能,有两种方式来实现。
引用服务的方式,通过在组件中允许引用服务接口的多个实现来实现组件功能的不断扩展,例如 A 组件的作用为显示菜单,它通过引用菜单服务接口来获取系统中所有的菜单服务,此时系统中有两个实现此服务的组件,分别为文件菜单组件和编辑菜单组件,那么 A 组件相应地就会显示出文件菜单和编辑菜单,而当从系统中删除编辑菜单的组件时,A 组件显示的菜单就只剩文件菜单了,若此时再部署一个实现菜单服务接口的视图菜单组件模块到系统中,那么显示出来的菜单则会为文件、视图。
定义扩展点的方式,按照 Eclipse 推荐的扩展点插件的标准格式定义 Bundle 中的扩展点,其他要扩展的 Bundle 可通过实现相应的扩展点来扩展该 Bundle 的功能。 系统对于可扩展性的需求很大程度会影响到 Bundle 的划分和设计,这要结合实际情况来进行设计。