2009-03-03 09:21:43 来源:51CTO
第一次接触OSGi 是2006年看见的一则网上新闻,该新闻中提到BMW 汽车的通信-娱乐(infotainment)系统采用了OSGi 架构,这套系统主要用来控制汽车上的音箱、灯光、导航和通讯等设备,整个系统由1000多个模块组成,启动时间却只需要3.5秒钟,这对于一个基于 Java 的框架来讲,具有两个重大意义:一、说明了Java 执行效率并不差;二、OSGi 框架的性能尤其优秀。因此笔者对OSGi 框架产生了极大的兴趣,后来终于在一个项目中负责研究和开发基于OSGi 框架的应用程序,从此对它便情有独钟。令人欣慰的是,OSGi 在2007年取得了诸多战果:BEA 公司、Eclipse 基金会和Interface21 公司相继加入OSGi 联盟;在EclipseCon 2007大会上引起了业界的广泛关注,其中以Spring-OSGi、Web Service 与OSGi 等技术最为引人注目,这也标志着OSGi 将在未来与企业应用紧密结合;OSGi R4 标准发布,相关内容被成功的写入JSR 291 规范中;Spring 2.5 框架的发布,宣称其所有jar 包都兼容OSGi 标准;虽然OSGi 没能成功进入JavaEE 6 草拟计划中,但是Sun 公司宣称会在下一代Java EE 标准中重点考虑OSGi。因此笔者个人认为,在不久的将来OSGi 势必会在企业应用中发挥出强大的作用,基于OSGi 框架的产品也将层出不穷。本文从OSGi 的历史背景、OSGi 的特点、OSGi 开源框架介绍、OSGi 开发环境部署、OSGi 版的Hello World 五个部分对OSGi 框架进行概要的介绍,希望读者能从中有所收获。
OSGi 的历史背景
什么是OSGi 呢?OSGi——Open Service Gateway Initiative 字面上的意思是一个公共的服务平台。1999年OSGi 联盟成立,它是一个非盈利的国际组织,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准,是开放业务网关的发起者。OSGi 联盟的初始目标是构建一个在广域网和局域网或设备上展开业务的基础平台。历史总是具有惊人的相似性,正如Java 诞生于一个嵌入式开发的项目中,却被应用于网络平台的开发,对OSGi 的最早设计也是针对嵌入式应用的,诸如机顶盒、服务网关、手机、汽车等都是其应用的主要环境。后来,由于OSGi 的诸多优秀特性(可动态改变系统行为,热插拔的插件体系结构,高可复用性,高效性等等),它被应用于许多PC 上的应用开发,因此逐步为开发者所知和钟爱。现在人们对OSGi 的理解已经远远不是它字面和初衷所能解释的了,笔者认为称其为一个轻巧的、松耦合的、面向服务的应用程序开发框架更为确切一些。
OSGi 真正被大家所知还是和Eclipse 有密切关系的。Eclipse 很多年都是Java 开发者的首选IDE,相信只要是一个Java 开发者,应该没有人不知道Eclipse 的。在Eclipse 3.0 以前的版本中,它本身有一套自身的插件体系,而该插件体系的设计非常精巧细致,受到许多开发者的推崇,但是Eclipse 基金在Eclipse 3.0 发布的时候,做出了一个大胆的行为,就是将Eclipse 逐步迁移到OSGi 框架中,并自己实现了一个OSGi 开源框架,取名为Equinox,该框架随着每次Eclipse 的发布也会相应的更新。Eclipse 之所以这么做,其一是因为Eclipse 的插件体系与OSGi 的设计思想不谋而合,其二也是因为OSGi 更为规范,其对插件体系的定义也更为完整一些。事实证明Eclipse 在采用OSGi 架构后,无论从性能、可扩展性这两个方面来讲还是从二次开发的角度来定义,都取得巨大的成功。下图展示了Eclipse 与OSGi 框架的关系。
OSGi 的特点
在介绍OSGi 框架的特点之前,先简单的介绍一下OSGi 框架的各个部分,如下图所示。
解释一下上图中每一层的含义,其中OS 层和JVM 层可以不用详细介绍了,重点需要关注的是应用程序Bundles 层。框架本身提供的类加载,生命周期管理,服务注册和规范服务也都是针对Bundles 的。每一个在OSGi 框架中运行的逻辑单元称为一个Bundle,Bundle 实际是一个符合特定形式的jar 文件。每一个Bundle 的功能可以是抽象的也可以是具体的。所谓抽象,就是它不是一个具体的应用,没有完成一些业务功能,而只暴露了一些接口或者功能给其他的Bundle 使用;所谓具体,就是该Bundle 可以独立的完成一个功能,例如连接数据库,获取数据等等。Bundle 有六种状态,分别是:installed(安装完成,本地资源成功加载),resolved(依赖关系满足,即该Bundle 要么是准备好运行了,要么是已经被停止了),starting(Bundle 正在被启动),stopping(Bundle 正在被停止),active(Bundle 被激活,正在运行中),uninstalled(Bundle 被卸载了)。OSGi 有它自身的类加载机制从而控制这些加载的Bundles 彼此之间的依赖关系,而生命周期管理也是OSGi 的一大亮点,由于可动态的对这些加载的Bundles 进行安装、卸载、启动、停止等操作,所以可以动态的改变应用程序的运行状态。当一系列的Bundles 存在于服务器中的时候,那么它们之间必然会存在通信协作的部分,比如说一个通过网页捕获用户输入的Bundle 执行的时候,它必须首先需要一个Web 服务器服务的支持,那么这个时候服务注册器就会从整个OSGi容器中寻找这个服务,如果能完成服务的匹配,那么相应的功能就会很自然的实现了。OSGi 规范还规定了一组预设的服务,包括日志、服务管理等等,这些服务在主流的开源框架中都有实现。OSGi 框架中还包括一个安全层,OSGi 的安全层扩展了Java 的安全机制,增并加了一些新的约束以填补了Java安全机制中的遗漏。
基于上述的介绍,读者想必应对OSGi 有个大致的概念了,那么接下来就让我们来看看OSGi 究竟能够给企业应用带来什么?它究竟有哪些功能值得我们把宝贵的时间投资在上面?
第一点,也是笔者认为最重要的一点,基于OSGi 的应用程序可动态更改运行状态和行为。笔者曾经参与过开发J2EE 企业级项目,应用服务器用的是IBM 的Websphere,主要开发基于EJB 2.1 的一些应用程序。整个开发经历给笔者的最深印象是等待,排除编写EJB 规范中要求的一系列繁杂的接口,单单对应用程序进行部署和测试,反复启动服务器就浪费掉很多时间。而在OSGi 框架中,每一个Bundle 实际上都是可热插拔的,因此,对一个特定的Bundle 进行修改不会影响到容器中的所有应用,运行的大部分应用还是可以照常工作。当你将修改后的Bundle 再部署上去的时候,容器从来没有重新启过,在外界看来,这种过程似乎从未发生过。这种可动态更改状态的特性在一些及时性很强的系统中尤其重要,比如说一个及时销售系统,当你的服务器因为要更新某个组件从而花上数分钟时间重新启动的话,必然导致客户的流失和利益的损失,但是采用OSGi 架构的应用则完全可以将损失降到最低。众所周知,Spring 框架以其优秀的特性,占据了当前企业应用开发的半边天空,而刚刚发布的2.5 版本,宣布所有jar 包均支持OSGi 特性,其维护的子项目Spring-OSGi 也是专门针对Spring 与OSGi 的集成。Spring 早前版本有一点被人所诟病,就是其无法动态的改变其运行状态,被迫停止服务器,再修改配置文件,而与OSGi 的结合,必然导致这种状态的终结。最后,笔者认为这种特性也保证了系统有足够的灵活性和可扩展性,对开发人员也大大节省了需要等待的时间。
第二点,它是一个稳定高效的系统。OSGi 是一个微核的系统,所谓微核是指其核心只有为数不多的几个jar 包。基于OSGi 框架的系统可分可合,其结构的优势性导致具体的Bundle 不至于影响到全局,不会因为局部的错误导致全局系统的崩溃。每个Bundle 也只有当服务被调用的时候才会启动,因此性能是较一般的框架高出许多。
第三点,可复用性强。OSGi 框架本身可复用性极强,很容易构建真正面向接口的程序架构,每一个Bundle 都是一个独立可复用的单元。但是采用OSGi 框架进行企业开发是需要气魄和勇气的,因为当前的软件企业,大多已经积累了许多年,都会遗留下来一些可复用的工具箱程序,而采用OSGi 架构需要重新对这些遗留系统进行封装,更有可能的是需要把整个体系架构打散了,进行重新的架构和排列。这个开发成本不能说是不高,但笔者认为是值得的,因为从此以后企业可以利用OSGi 独特的特性,将重复的知识轻易的过滤掉。对于新的开发,可以从企业的Bundles 库中精简出可复用的模块,量身定做新的Bundles,最大限度的利用了以前的积累,这样的过程更能促使企业竞争力的增强。
OSGi 开源框架介绍
当前的OSGi 开源框架主要包含如下几个:
Equinox
最知名,也是更新最频繁的,由于Eclipse 基金的支持,其功能越来越完善,笔者后续的具体开发都是基于该框架来实现的。当前已发布版本是3.3.1 与Eclipse 版本相同,实现了OSGi R4 规范,并提供很多平台性质的服务,包括:常用功能模块、日志模块、Web服务器模块、Servlet 模块、JSP 解析模块等等。由于其与Eclipse 的天然联系,使得开发基于Equinox 的应用程序变得很简单,笔者推荐采用此框架进行二次开发
Knopflerfish
很早的,也很优秀的一个OSGi 框架,也实现了OSGi R4 标准,去年十一月发布了其2.0.2版本。该项目的宗旨在于创建一个易于开发的OSGi 平台,与Equinox 不同之处在于它本身提供一些小应用实例,包括一个可视化控制台等,也提供基于Eclipse 的插件。
Felix
很新的一个OSGi 框架,社区很活跃,更新频率高,是Apache 的开源项目。该项目2007年8月才出1.0 版,也实现了OSGi R4 规范,也提供相关的基础服务和扩展服务功能。
OSGi 开发环境部署
讲了那么多原理,如果不动手实践一下,总是难以令人信服的。那么现在我们就开始动手搭建开发环境吧。
首先,你需要准备好Eclipse 笔者用的是Eclipse 3.3.1 ,还有从Equinox 网站上下载到的Equinox SDK。
其次,将Equinox SDK 解压,解压后是一个Eclipse 目录,将该目录下的所有内容拷贝至你的Eclipse 安装目录下,就像平时手动安装Eclipse 插件一样。
最后,测试下是否安装成功。启动你的Eclipse,选择Run>Open Run Dialog…在弹出的界面中,如果出现了OSGi Framework 的选项,那基本上就是成功了。点击新建一个OSGi Run方式,这时会列出一系列的加载组件,你可以检查一下,如果里面有org.eclipse.osgi ,org.eclipse.osgi.services 和一系列以org.eclipse.equinox 开头的组件,那么就真的安装成功了。选中org.eclipse.osgi 和org.eclipse.osgi.services,点击Run 按钮,控制台会出现“osgi>”的提示,输入“ss”,就会看到你运行的这两个Bundles 的ID和状态了。每次输入错误的时候,控制台会打印出完整的命令列表,读者可以在此参考。
OSGi 版HelloWorld
到了真的写一个HelloWorld 的时候了,该应用设计如下图:
这个应用包含五个Bundles:SayHello Bundle 包含一个接口,只有唯一的方法sayHello();BobSays、RodSays、KentSays 三个Bundles 分别实现了三个具体的sayHello();而SayHelloService Bundle 提供了说hello 的机会,是具体的一个服务应用,在功能上有点类似于main 函数的味道。这个HelloWorld demo 的目的不但可以让读者小试牛刀,而且可以同时体会一下OSGi 最大的优点——服务状态的可更改性。BobSays、RodSays、KentSays 实现了SayHello 暴露的接口,它们是sayHello 的具体执行者,但是在SayHelloService 调用的过程中,我们可以动态的改变到底是谁来说。为了实现这个demo,还需要简单介绍一下OSGi 最简单的实现机制:OSGi Bundles 之间包的依赖关系。每一个OSGi Bundle 的类文件可分为私有的、引入的、暴露的三种,如下图所示
免责声明:本网站(http://www.ciotimes.com/)内容主要来自原创、合作媒体供稿和第三方投稿,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证有关资料的准确性及可靠性,读者在使用前请进一步核实,并对任何自主决定的行为负责。本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。