模块的组织
OSGi不会出现需要引用其他模块Bundle的情况,只需引用接口。
模块的复用和扩展
只需要将Bundle部署上去即可为系统增加相应的模块。
OSGi吸取了Eclipse
plugin中Extension Points的思想。
Equinox作为OSGI
R4的RI,Equinox除了完整实现OSGI R4规范外,最重要的就是Extension Registry,它是Eclipse插件机制中关键的部分,它为插件的扩展提供了一种实现的机制。Bundle通过发布扩展点的方式来定义Bundle可扩展的部分,当需要扩展Bundle的时候只需要实现Bundle提供的扩展点的接口就可以了。
如果开发要保证符合OSGI标准,那么就不要使用Equinox对于OSGI的扩展,这个在使用Eclipse进行开发时可以指定仅使用标准的OSGI框架。
可插拔的系统
可通过安装新的Bundle、更新或停止现有的Bundle来实现系统功能的插拔。
可插拔、可动态改变行为从根本上保证了系统在运行期足够的灵活性和扩展性。
稳定、高效的系统
OSGI采用微核机制,微核机制保证了系统的稳定性,微核机制的系统只要微核是稳定运行的,那么系统就不会崩溃,基于OSGI的系统不会受到运行在其中的Bundle的影响,不会因为Bundle的崩溃而导致整个系统的崩溃。
延迟加载,只有在请求发生时OSGI才去完全加载、启动相应的Bundle、Service。
规范的、可积累的模块
基于OSGI的系统采用规范的模块开发、部署方式构建系统。
OSGI框架是一个微核结构的容器,所有的模块都需要运行在容器范围内,在OSGI中所有模块的部署都必须以Bundle的方式来进行部署
Bundle就是一个jar文件,在OSGI框架中是采用Bundle的方式来组织和部署系统的。Bundle通过实现BundleActivator接口去控制其生命周期,在Activator中编写Bundle启动、停止时所需要进行的工作,同时也可以在Activator中发布或者监听框架的事件状态信息,以根据框架的运行状态做出相应的调整。BundleActivator类是可以不需要的,建议不要在BundleActivator中初始化过多的东西,这样会使得系统的启动速度会变得很慢,同时也会消耗大量的内存。
在OSGI框架中对于每个Bundle采用的是独立的classloader机制。借助使用Bundle的元数据来实现工程之间package的共享。
在OSGI框架中对于每个Bundle可以定义输出的包以及引用的包,这样在Bundle间就可以共享包中的类了,直接实现简单的Bundle的协作。
Bundle采用Require-Bundle的方式来直接引用其他的Bundle
每个Bundle可以通过BundleContext注册对外提供的服务,同时也可以通过BundleContext来获得需要引用的服务。和Import-Package、Require-Bundle不同的地方在于通过Service获取的是其他Bundle中类的实例。
OSGI R4规范
Module Layer
Bundle的元数据属性的值,都支持增加附加过滤属性的方式:版本过滤、Bundle元数据信息过滤、自定义属性过滤
Lifecycle Layer
Bundle的状态:
INSTALLED
Bundle已经成功的安装了。
RESOLVED
Bundle中所需要的类都已经可用了,RESOLVED状态表明Bundle已经准备好了用于启动或者说Bundle已被停止。
STARTING
Bundle正在启动中,BundleActivator的start方法已经被调用,不过还没返回。
ACTIVE
Bundle已启动,并在运行中。
STOPPING
Bundle正在停止中,BundleActivator的stop方法已经被调用,不过还没返回。
UNINSTALLED
Bundle已经被卸载了。
管理Bundle的状态时,OSGI主要是通过Bundle、BundleContext这两个对象来实现。
Service Layer
Service通过BundleContext完成注册和获取。
Declarative
Services(声明式服务)
Component
对外提供Service;
使用其他Component提供的Service;
交由OSGI框架管理生命周期。
Service的发布和引用,component.xml
模块化设计
真正意义的模块化,模块的设计更加的完善和规范
面向服务的组件模型设计
面向服务的组件模型设计则是对模块进行详细设计时的核心思想。
Component通过引用Service或暴露Service来完成模块中用例的实现,面向服务的组件模型设计更加强调在设计时分解模块中用例的实现(形成组件和服务)以及组件依赖的关注。
动态性设计
要充分的发挥基于OSGI的动态性,就要完全的采用面向接口的设计方式,而不是去依赖实现,要记住基于OSGI搭建的系统是在运行期才构成依赖的。设计基于OSGI的系统时特别要注意依赖不要在设计时就定死
面向接口的开发
OSGI为每个Bundle提供独立的ClassLoader机制,使得基于OSGI的系统让我们在开发时真正的做到面向接口的开发。
在基于OSGI框架进行开发时应该养成对外Export接口的packages,而隐藏实现接口的packages,更为好的方法就是把接口单独的放入一个Bundle中,这样对于更换接口的实现就更为方便了。