`

OSGI学习笔记(五)

阅读更多

开放服务网关协议 (Open Services Gateway initiative),简称OSGi,为网络服务定义了一个标准的、面向服务的计算环境,为用户提供了开放的、面向服务组件的、易于部署的编程模型,这个编程模型允许用户将定义好的接口规范绑定到OSGi运行环境中的特定Service,在构建SOA 面向服务为中心的企业应用的过程中,OSGi 技术正发挥越来越重要的作用。



OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的是为嵌入式设备,确切地说是为可以通过网络访问的设备提供一个通用的软件运行平台,屏蔽不同设备之间的硬件和操作系统差异,使软件可以动态地部署和更新。后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一个子项目 Equinox 来实现 OSGi R4 规范,把 Equinox 作为 Eclipse 的底层运行平台。



OSGi框架是一个微核结构的容器,所有的模块都需要运行在容器范围内,在OSGi中所有模块的部署都必须以Bundle的方式来进行部署。OSGI官方称是面向服务的系统架构,也可以理解为面向组件的架构,系统中每一个组件或者一个模块称之为bundle,这也是OSGI里最基本的单元。



OSGi框架提供了一套完善的机制用于管理和控制组件(Bundle)、服务(Service)的生命周期,以及组件和服务在其生命周期内的交互。



Bundle其实就是一个jar文件,这个jar文件和普通的jar文件唯一不同的地方就是META-INF目录下的MANIFEST.MF文件的内容。三种特殊形式的Bundle是:

1、Require Bundles:可以直接被其他Bundle通过Require-Bundle来使用的Bundle。
2、Fragment Bundles:它本身并不拥有独立的classloader,可以把它看成是Bundle的一种附属,它通过在元数据中指定Fragment-Host来说明其所依附的Bundle,只有在该Bundle使用时才会激活到这个Fragment Bundle。
3、Extension Bundles:它用于扩展system bundle,通过Fragment-Host指定到system bundle的方式来实现对system bundle的扩展。



在OSGi框架中对于每个Bundle采用的是独立的ClassLoader机制,所以,Bundle之间的协作一是为每个Bundle定义其输出的包以及引用的包,以此来共享包中类,二是采用Service的方式。



OSGi亦称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构。OSGi容器已有多家开源实现,比如Equinox、Knoflerfish和Apache的Felix等。您可以通过这些容器,把您的应用程序劈分为多个模块单元,这样,您就可以更容易地管理这些模块单元之间的交叉依赖关系。



一、OSGi 体系结构:

OSGi 的体系架构是基于插件式的软件结构,包括一个 OSGi 框架和一系列插件,在 OSGi中,插件称为 Bundle,其中,OSGi 框架规范是 OSGi 规范的核心部分,它提供了一个通用的、安全可管理的 Java 框架,通过这个框架,可以支持 Bundle 服务应用的部署和扩展。Bundle 之间可以通过 Import Package 和 Require-Bundle 来共享 Java 类,在 OSGi 服务平台中,用户通过开发 Bundle 来提供需要的功能,这些 Bundle 可以动态加载和卸载,或者根据需要远程下载和升级。


Execution Environment:Bundle 应用所倚赖运行的 Java 执行环境,如 J2SE-1.4、CDC-1.0 等都是可用的执行环境。



Modules:模块层定义了 Bundle 应用的加载策略。OSGi 框架是一个健壮并且严格定义的类加载模型。在大多数 Java 应用中,通常只有一个单独的 ClassPath,它包含了所有的 Java 类文件和资源文件,OSGi基于Java技术,对于每个实现了 BundleActivator 接口的 Bundle 应用,为它生成一个单独的 ClassLoader,使得 Bundle 应用的组织更加模块化。



Life Cycle:生命周期层可以动态地对 Bundle 进行安装、启动、停止、升级和卸载等操作。该层基于模块层,提供了一组 API 来控制 Bundle 应用的运行时操作。



Service Registry 和 Services:OSGi 服务层定义了一个集成在生命周期层中的动态协作模型,是一个发布、动态寻找、绑定的服务模型。一个服务通常是一个 Java 对象实现了特定的服务接口,并且通过服务注册,被绑定到 OSGi 的运行环境中。Bundle 应用可以注册发布服务,动态绑定服务,并且在服务注册状态改变时,可以接受到事件消息等。



Security:OSGi 的安全管理是基于 Java2 安全体系的,贯穿在 OSGi 平台的所有层中,它能够对部署在 OSGi 运行环境中的 Bundle 应用进行详细的管理控制。



二、Bundle生命周期的状态:


INSTALLED:安装完成,本地资源成功加载。
RESOLVED:依赖关系满足,这个状态意味该Bundle要么已经准备好运行,要么是被停止了。
STARTING:Bundle正在被启动,BundleActivator的start()方法已经被调用但是还没有返回。

ACTIVE:Bundle 被成功启动并且在运行。
STOPPING:Bundle正在被停止,BundleActivator的stop()方法已经被调用但是还没有返回。
UNINSTALLED:bundle被卸载并且无法进入其他状态。



OSGi中所说的bundle有三种稳定状态:installed,resolved,active:

1、当一个激活的bundle停止时,在它的生命周期中它所导出的任何服务也将被自动反注册,并且bundle返回到resolved状态。停止的bundle会释放所有它所获取的资源,终止所有的线程。停止的bundle所导出的Packages仍然对其它bundles可用。
2、处于resolved状态的bundle可以被卸载:被卸载的bundle所导出的packages也仍然对其它导入它们的bundles可用(除了新安装的bundles)。
3、处于resolved状态的bundle也可以被更新。更新使得bundle从一个版本迁移到另一个版本。
最后,处于resolved状态的bundle可以被启动,使它的状态转移到active状态。
4、OSGi PackageAdmin refreshPackages操作刷新所有OSGi框架的包或者是已安装的bundles的给定的子集。在刷新期间,受其影响的bundle中的application context将会被停止并重新启动。refreshPackages操作完成后,被更新的bundle的原有版本导出的包不再可用。



三、Bundle的元数据信息

Bundle-Activator:Bundle的Activator类名。
Bundle-Category:Bundle的分类属性描述。
Bundle-Classpath:Bundle的Classpath。
Bundle-ContactAddress:提供Bundle的开发商的联系地址。
Bundle-Copyright:Bundle的版权。
Bundle-Description:Bundle的描述信息。
Bundle-DocURL:Bundle的文档URL地址。
Bundle-Localization:Bundle的国际化文件。
Bundle-ManifestVersion:定义Bundle所遵循的规范的版本,OSGI R3对应的值为1,OSGI R4对应的值为2。
Bundle-Name:Bundle的有意义的名称。
Bundle-NativeCode:Bundle所引用的NativeCode的地址。
Bundle-RequiredExecutionEnvironment:Bundle运行所需要的环境,如可指定为需要OSGI R3、Java 1.4、Java 1.3等。
Bundle-SymbolicName:Bundle的唯一标识名,可采用类似java package名的机制来保证唯一性。
Bundle-UpdateLocation:Bundle更新时连接的URL地址。
Bundle-Vendor:Bundle的开发商。
Bundle-Version:Bundle的版本。
DynamicImport-Package:Bundle动态引用的package。
Export-Package:Bundle对外暴露的package。
Fragment-Host:Fragment类型Bundle所属的Bundle名。
Import-Package:Bundle引用的package。
Require-Bundle:Bundle所需要引用的其他的Bundle。



四、模块层的主要功能机制

一)模块的包共享机制

通过使用Import-Package和Export-Package来实现Bundle的包的提供和引用。
1、过滤引用的包
版本过滤
Import-Package: org.riawork.opendoc.osgi;version=”1.0” 指定版本号
Import-Package: org.riawork.opendoc.osgi;version=”[1.0,2.0]” 指定版本范围
Bundle元数据信息过滤
Import-Package: org.riawork.opendoc.osgi;bundle-symbolic-name=com.cjm.bundle
自定义属性过滤
Export-Package:org.riawork.opendoc.osgi;company=cjm 自定义属性company
Import-Package:org.riawork.opendoc.osgi;company=cjm

必须的属性过滤
Export-Package:org.riawork.opendoc.osgi;company=”cjm”;security=false;mandatory:=security 通过mandatory指定必须匹配的属性
Import-Package:org.riawork.opendoc.osgi;company=cjm 导入包时必须包含security属性才能正确引用包
2、包约束
在引用包时注意包的版本号等相关信息
3、限定导出的包中的类
Export-package: org.riawork.opendoc.osgi;exclude:=”*Impl”;include=”Val*”
4、动态获取引用的包
通过DynamicImport-Package元数据的方式
DynamicImport-Package:org.riawork.opendoc.osgi
通过Resolution来指示
Import-package: org.riawork.opendoc.osgi;resolution:=optional



二)模块的类加载机制



三)模块的国际化

默认国际化文件的目录为:OSGI-INF/l10n,配置文件名为类似bundle_语言_国家_变量.properties。
中通过Bundle-Localization元数据来指定国际化文件所在的目录。
在使用国际化文件的情况下,在MANIFEST.MF文件中可采用%属性名的方式来使用国际化文件中的配置:Bundle-Name: %BundleName



四)模块的校验

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics