1.简述
随着OSGi越来越被大家所熟知,基于OSGi的开发成为一种趋势。在OSGi中,两个核心元素是Bundle和Service,本文仅涉及Bundle,Service不在讨论范围之内。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
OSGi中的Bundle通常被看做是一个细粒度的功能模块,为整个基于OSGi的系统提供某项功能。但是,Bundle的资源组织特性,使其可以不仅仅作为一个功能模块,也可以作为资源组织模块来应用。Bundle的资源组织特性是Bundle的功能特性的基础支撑。Bundle的资源组织特性可以在某些特定应用中得到充分的利用,本文就Bundle的资源组织特性在一类特定需求中的应用及各种实现方案做了详细的阐述,并提供了一种另类的实现。
为了更好的区分Bundle的功能特性和资源组织特性,我们在下面的讨论中将这两种不同侧重点的Bundle分别称之为“功能Bundle”和“资源Bundle”。
2.OSGi Bundle的特点
OSGi框架为基于Java的系统开发提供了灵活的动态模块化支持。OSGi的模块层(Module Layer)为Java组件模块化提供了一种标准的解决方案。在OSGi中, Bundle部署成为一个Java Archive(JAR)压缩(ZIP格式)文件,该文件包含的内容有:提供某些功能的资源文件,如Java类文件,帮助文件,HTML文件,配置文件等等;一个元数据文件,用于描述该压缩文件的信息及其内部所包含的资源,OSGi框架使用这些元数据信息来安装并激活Bundle。
在OSGi中,每一个Bundle具有自己独有的ClassSpace(详细信息参考OSGi规范)边界,Bundle间通过导出(Export)内部Java类,导入(Import)其他Bundle导出的Java类,来构造自己的ClassSpace边界。
Bundle之间也可以设定依赖关系,一个Bundle可以通过元数据Require-Bundle头来描述一个Bundle所依赖的其他Bundle列表。
OSGi中的Bundle接口提供了方法用于获取Bundle内部存储的资源,加载Bundle内部的Java类,通过实现BundleActivator接口获取BundeContext与其他Bunde进行交互。
3.资源Bundle的应用需求
在现实环境中,应用系统为了提高适应性和可扩展性,系统的设计开发越来越依赖于配置而不是硬编码。不同的系统,根据各自特点的不同,对于配置的依赖程度是不同的。下面以企业应用集成中的EAI中间件实现为例说明配置资源对于系统的重要性。
举例来说,存在待集成的两个系统,一个系统提供数据库访问接口,另一个系统提供WebService接口。为了实现这两个系统的集成,可以选择如下方式:
1.为此次集成需求做特定开发。这是最差的一种实现方式。
2.为数据库访问和WebService访问接口开发尽可能通用的模块,根据此次需求的差异性,对这些模块做适当定制开发。这是实际应用中最常见的实现方式。
3.开发通用的数据库访问接口和WebService访问接口模块,通过配置来处理实际需求的差异性。此种方式最为完美,但对模块的设计具有更高的要求。
EAI中间件系统为了能够集成各种各样的应用系统,必须采用上述第三种方式,因此,EAI中间件的实现高度依赖配置。
系统集成的复杂度依赖与系统业务的复杂度,简单的系统集成可能仅需要一种或几种配置即可满足需求;但是对于复杂的业务系统集成需求,可能存在几十中甚至上百种配置。很明显的一个示例是两个应用系统之间需要传输几十种业务报文,随着业务的不断发展变化,业务报文的内容和数量在随时产生变化。采用上述三种方式中的前两种方案来解决此种需求就要面临不断地进行维护和开发的成本,而采用第三种方案则可以避免开发而仅仅维护配置,维护成本将大大降低。
下面我们来看一下资源Bundle在上述需求中的充当配置资源的优势:
l集中的资源配置控制。可以将各种配置分散到各个资源Bundle中,通过OSGi框架统一管理这些资源Bundle。
l资源配置的生命周期控制。资源Bundle在OSGi中具有生命周期,可以控制资源Bundle的安装,卸载。
l资源配置的状态处理。资源Bundle在OSGi中的状态变化会产生事件,通过监听这些事件,可以对资源Bundle的各种状态进行内部处理。如可以捕获资源Bundle的安装事件对Bundle中的资源文件进行有效性检查。
l资源配置可以包含程序代码。系统在处理某种资源配置时可能需要为此种配置提供特定的程序扩展实现,使用资源Bundle就可以将扩展代码与资源配置打包在一起,进行统一管理。实际应用中最常见的例子是Java实体Bean。
l资源Bundle的类空间(ClassSpace)隔离。现实应用中,不同的用户可能共同使用同一个系统,并在此系统中设计自己的资源配置,如果用户的资源配置中可以包含Java类代码,则利用资源Bundle可以避免用户间的类代码冲突。
l资源Bundle之间的依赖关系。OSGi Bundle之间可以设定依赖关系,作为资源Bundle也可以设定对其他资源Bundle的依赖,这种依赖限定可以为资源配置提供额外的可靠性约束。
资源Bundle在不同的应用中所体现的优势可能不同,大家可以充分结合实际需求来利用。
4.资源Bundle的应用方案
4.1.功能Bundle即资源Bundle
前述说过,资源Bundle是功能Bundle的基础,功能Bundle也是一个资源Bundle,如果该功能Bundle的配置资源比较固定并且简单,可以直接将配置资源放置于该Bundle内。此种方案在基于OSGi开发的系统中来的最为直接。
4.2.在OSGI中资源Bundle与功能Bundle分离
某些功能Bundle可能需要多种资源配置,而各种资源配置可能具有自己的变更周期,为了不影响其他配置的使用,可以将这些配置拆分成独立的资源Bundle,由功能Bundle根据需要查找使用。
为了区分功能Bundle和资源Bundle,可以通过定制OSGi元数据头信息来实现。如在MANIFEST.MF文件中添加Bundle-Type: Resource的自定义属性来标明该Bundle是资源Bundle。并利用其他定制属性来标明该资源Bundle的具体业务信息。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="图片_x0020_1" style="VISIBILITY: visible; WIDTH: 369pt; HEIGHT: 213pt; mso-wrap-style: square" type="#_x0000_t75" o:spid="_x0000_i1027"><imagedata o:title="" src="file:///C:/DOCUME~1/ChrisRc/LOCALS~1/Temp/msohtmlclip1/01/clip_image001.png"></imagedata></shape>
如上图所示,功能Bundle和资源Bundle处于同一个OSGi框架之内。功能Bundle通过BundleContext可以查找资源Bundle并获取资源Bundle内的资源。这种方式的前提是系统必须基于OSGi框架开发。
4.3.传统应用利用OSGi作为资源配置中心
在传统应用中利用OSGi来作为资源配置中心,就需要将OSGi框架内嵌到自己的应用系统中。透过内嵌的OSGi框架获取该框架所管理的所有资源Bundle。目前,在各种OSGi的开源实现中,Felix为内嵌应用提供了很好的支持。
关于如何内嵌Felix,请参考Felix项目网站的相关文档。
<shape id="图片_x0020_4" style="VISIBILITY: visible; WIDTH: 326.25pt; HEIGHT: 198.75pt; mso-wrap-style: square" type="#_x0000_t75" o:spid="_x0000_i1026"><imagedata o:title="" src="file:///C:/DOCUME~1/ChrisRc/LOCALS~1/Temp/msohtmlclip1/01/clip_image003.png"><font color="#000000" size="3"></font></imagedata></shape>
4.4.在OSGi环境中利用OSGi作为资源配置中心
如前所述,资源Bundle和功能Bundle可以在同一个OSGi框架中共存,各个功能Bundle透过BundleContext控制和获取所需的资源Bundle中的资源,但是,此种应用方案存在明显的弊端,资源Bundle和功能Bundle混杂在一起难于控制,随着资源Bundle数量的增多,系统将会越来越复杂。
理想的解决方式就是将资源Bundle和功能Bundle分离,为资源Bundle提供单独的OSGi环境。因此,可以将OSGi框架实现作为一个独立的功能Bundle(反转OSGi,非System Bundle)作为资源Bundle的控制中心和入口点。如下图所示。
<shape id="图片_x0020_9" style="VISIBILITY: visible; WIDTH: 369pt; HEIGHT: 262.5pt; mso-wrap-style: square" type="#_x0000_t75" o:spid="_x0000_i1025"><imagedata o:title="" src="file:///C:/DOCUME~1/ChrisRc/LOCALS~1/Temp/msohtmlclip1/01/clip_image005.png"><font color="#000000" size="3"></font></imagedata></shape>
5.结论
OSGi为Java模块化系统开发提供了一种强大的解决方案。OSGi框架中所包含的各种设计思想可具有很高的利用价值。在OSGi环境中利用OSGi作为资源配置中心是一个很有意思的构想,在此构想的实现中过程中我们会面临一些非常有挑战的问题。在后续文档中我会逐步给出这种构想的实现。
相关推荐
### Eclipse-OSGi内核源码分析:深入理解Bundle接口 #### 1....Eclipse-OSGi通过提供强大而灵活的`Bundle`接口,使得构建高度模块化和可扩展的应用程序成为可能,为现代软件工程提供了强大的支撑。
例如,可以使用Bundle.getResource或Bundle-ClassPath来访问内部资源。此外,当多个bundle共享同一个properties文件时,可能需要考虑资源的加载顺序或者实现一种全局的配置共享机制。 接下来是事务管理,这是一个...
综上所述,"JMX.rar_jmx_osgi"文件包提供了一套完整的JMX开发资源,涵盖了从基础概念到实际应用的各种方面,特别是与OSGi的集成,这对于理解和实践JMX技术非常有帮助。通过深入研究这些jar包和示例,开发者能够更好...
1. **Bundle Format And Manifest Headers**:为了正确打包Spring DM应用,需要了解并设置正确的Bundle格式和Manifest头,以确保应用能够在OSGi环境中顺利运行。 2. **Extender Configuration Options**:Spring DM...
在RSP4J中,每个服务或模块都被封装为一个独立的OSGi bundle,这样可以轻松地添加、移除和更新功能,而不会影响到整个系统的运行。例如,`org.rsp.resource`可能是负责资源管理的服务,`org.rsp.example....
此外,讲解了bundle启动和plug-in启动的两种情况,包括依赖启动、服务调用启动和扩展加载启动,强调了被动调用与主动调用的区别,并提示分析扩展加载过程中类加载器的角色。 最后,Eclipse的启动过程也进行了详解,...
- **Bundle.properties**:Eclipse使用Java的Resource Bundle机制,每个插件或视图都有一个对应的`.properties`文件,用于存储国际化字符串。 - **OSGi服务**:通过OSGi服务,Eclipse可以动态加载和使用不同语言的...
这通过使用资源包(Resource Bundle)和国际化API来实现。 8. **性能优化**:由于SWT直接调用操作系统API,相比Swing,它在某些场景下可能有性能优势,尤其是在处理大量数据或复杂的用户交互时。 9. **拖放功能**...
- Eclipse采用插件化架构,每个功能模块都是一个插件,通过OSGi(开放服务网关规范)框架进行管理和交互。 - 插件之间的依赖关系通过manifest.mf文件中的 Require-Bundle 或 Import-Package声明。 - Platform ...