精品
OSGI框架从功能上分为下面几个层次:
安全层 Security Layer 模块层 Module Layer
生命周期层 Life Cycle Layer 服务接口层 Service Layer
安全层:
OSGi安全层是OSGi服务框架的一个可选的层。它基于Java 2 安全体系结构,提供了对精密控制环境下的应用部署和管理的基础架构。
OSGi服务平台采用两种方式对代码进行校验: 位置验证 签名验证
模块层:
Module Layer定义了在OSGI框架中是怎么去按照Module的思想去开发的。
框架定义了模型化单元,称之为一个 bundle。一个bundle由java的类和其他资源组成,可以为终端用户提供功能。通过良好定义的方式,Bundle 可以和导入(importer)及导出
(exporter) Bundle之间共享Java包。
在OSGi服务框架中,bundle是仅有的需要部署的Java应用实体。 Bundle以JAR文件的方式进行部署。 一个bundle是一个如下的JAR文件:
拥有提供服务所必须的资源。这些资源可以是 java的class文件,或者是其他的
数据如HTML文件,帮助文件,图标文件等。一个bundle JAR文件也可以嵌入其他JAR文件作为资源,但是不支持多层嵌套的JAR。
有一个manifest文件描述JAR文件内容和bundle的信息。该文件处于JAR的头部,
提供框架需要的安装和激活bundle所需的信息。例如,它对其他资源如 JAR文件的依赖这种状态信息必须在bundle运行之前加载。
可以在OSGI-OPT文件夹提供可选的文档信息,该文件夹可以位于 JAR文件根目录
或者它的子文件夹中。OSGI-OPT文件夹中的内容都是可选的。例如,可以在其中保存 bundle的源代码。管理系统可以删除该文件夹内容,以便于节约OSGi服务平台的存储空间。当一个bundle开始运行,通过OSGi服务平台,它开始对安装在平台内的其他bundle提供功能和服务。
Bundle 的描述信息在一个 manifest 文件中,在 JAR 文件中的 META-INF 目录下的MANIFEST.MF文件。框架在manifest文件头中定义了Export-Package和Bundle-Classpath这样的OSGi manifest 头,bundle的开发人员可以使用它们提供 bundle的描述信息。
类加载机制:
许多bundle可以共享虚拟机(VM)。在VM内部,bundle可以相互隐藏包和类,也可以和其他bundle共享包。
可编辑
精品
隔离和共享包关键是由java的类加载器来实现,类加载器通过仔细定义的规则从bundle空间的一个子集中加载类。每一个bundle只会有一个单独的类加载器,类加载器形成了一个类加载的代理网络结构,如下所示:
类加载器可以加载类和资源,加载途径有:
启动类路径:启动类路径中有一个java.*的包以及它实现的包。
框架类路径:在框架中通常有一个单独的类加载器,加载框架实现的类和关键的服务接口类。
Bundle类空间:bundle的类空间由和bundle相关的JAR文件组成,以及其他和bundle紧密相关的JAR文件,比如bundle片断类空间是指一个给定的bundle类加载器可以访问到的所有的类。因此,一个指定bundle的类空间来自:
父类加载器(通常是来自启动类路径的java.*包中的) 导入的包
必须的bundle
Bundle类路径(私有包) 附加的片断
类空间必须是一致的,也就是说不能存在相同全名的两个类(为了防止类声明错误)。 但是,在OSGi框架中,不同的类空间可以存在同名的类。在模块层,支持不同版本的类加载到相同的虚拟机中。
在使用一个 bundle之前,框架必须对共享的包之间的约束关系进行解析。解析过程就是确定导入包如何连接到导出包。
bundle的 package共享机制
在开发中可以直接通过import-package方式来引用所需要的package。通过export-package方式来导出对外暴露才包。
也可以在import-package中或者export-package中设置其过滤属性,以更加准确的获取或导出所需要的package。
可以通过版本过滤、元数据信息过滤、自定义属性过滤、必须的属性过滤来实现过滤获
可编辑
精品
取或导出package。
可编辑
精品
生命周期层:
bundle可以处于以下状态中的一种: INSTALLED — 成功安装bundle
RESOLVED — 所有bundle需要的Java类都准备好了。这个状态标志着 bundle已经是启动就绪或者是已经停止。
STARTING — 正在启动bundle。调用了bundle激活器的start方法,而且还没有从方法中返回。
ACTIVE — bundle已经启动完毕,正在运行中。
STOPPING — 正在停止bundle。调用了bundle激活器的stop方法,而且还没有从方法中返回。
UNINSTALLED — bundle已经卸载完毕,不能进入其他状态。
? 安装 Bundle
通过 BundleContext 的 installBundle 方法来安装 Bundle,在安装前首先需要对 Bundle进行校验,如校验通过, OSGI 框架中将安装 Bundle到系统中,此时 OSGI 框架会分配一个高于现在系统中所有的 Bundle 的 ID 给新的Bundle,安装完毕后 Bundle 的状态就变为 INSTALLED 了,同时会返回bundle 对象,在 Bundle 安装后就要使用 bundle 对象来管理 Bundle 的生命周期状态了。
? 解析 Bundle Bundle 安装完毕后,OSGI 框架将对 Bundle 进行解析,以检测 Bundle 中的类依赖等是否正确,如有错误则仍然处于 INSTALLED 状态,如成功Bundle 的状态则转变为 RESOLVED。
可编辑
精品
? 启动 Bundle
在启动 Bundle 前需检测 Bundle 的状态,如 Bundle状态不为 RESOLVED,那么需要先解析 Bundle,如启动一个解析失败的 Bundle,则会抛出BundleException,但此时 Bundle 的状态仍然会被设置为 ACTIVE;如Bundle 的状态已经是 ACTIVE, 那么启动 Bundle对它不会产生任何影响。
通过 BundleContext 的 getBundle 方法可获取指定 Bundle ID 的 Bundle 对象,在获取到Bundle对象后可使用Bundle对象的start方法来启动Bundle,此时会调用 MANIFEST.MF 中的 Bundle-Activator 属性对应的BundleActivator 类的 start 方法(如存在 BundleActivator 类),在 start 方法执行的过程中 Bundle 的状态为 STARTING,当 start 方法执行完毕后Bundle 的状态转变为 ACTIVE,如 start 方法执行失败,Bundle 的状态转变为 RESOLVED。
? 停止 Bundle
通过 BundleContext 的 getBundle 方法可获取指定 Bundle ID 的 Bundle 对象,在获取到Bundle对象后可使用Bundle对象的stop方法来启动Bundle,此时会调用 MANIFEST.MF 中的 Bundle-Activator 属性对应的BundleActivator类的 stop方法,在 stop 方法执行的过程中 Bundle 的状态为STOPPING,当stop方法执行完毕后Bundle的状态转变为RESOLVED,如 stop 方法执行失败,Bundle 的状态则继续保留原状态。 即使 Bundle 已经停止,其 export 的 package 仍然是可以使用的,这也就意味着可以执行 RESOLVED状态的 Bundle 中 export package的类。
? 卸载 Bundle
通过调用 Bundle 对象的uninstall 方法可完成 Bundle 的卸载, 此时 Bundle的状态转变为 UNINSTALLED。 即使 Bundle已卸载,其 export 的package 对于已经在使用的 Bundle 而言仍然是可用的,但对于新增的 Bundle 则不可使用已卸载的 Bundle export的 package。
? 监听 Bundle的状态
在监听 Bundle 的状态上 OSGI 采用的是典型的 Java 中的事件机制,在 OSGI中事件分为 Framework Event和 Bundle Event 两种,Framework Event 用于报告 Framework 已启动、改变了 StartLevel、刷新了 packages或是出现了错误;而 Bundle Event 则用于报告 Bundle 的生命周期的改变。 可通过实现BundleListener或SynchronousBundleListener来监听Bundle Event,可通过实现 FrameworkListener来监听 Framework Event。
服务层:
Service Layer定义了 Bundle 动态协作的服务发布、查找和绑定模型,Service Layer 基于 Module Layer和 Lifecycle Layer,使得 OSGI 形成了完整的动态模型。
不过 Service Layer 的定义比较简单,是一个典型的 Service Locator 模式的模型, Service 通过BundleContext 完成注册和获取。
? 服务的注册
可在任何时候通过 BundleContext的 registerService 方法来完成服务的注册,和其他的服务框架一样,在 OSGI 中注册服务时也可以注册一个 ServiceFactory的类,服务成功注册后会返回 ServiceRegistration 对象,通过这个对象的unregister方法可卸载服务。
可编辑