OSGi架构研究

系统 1357 0

OSGi 架构研究

OSGi 概述

       OSGi Open Service Gateway Initiative 的简称,该组织建立于 1999 年,是一个非赢利机构,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准。 OSGi 并不是专为家庭网络而制定的,除了住宅网关,像车载电脑等其他移动嵌入式设备也都可以通过 OSGi 接入 Internet ,获取不同的应用服务。它为服务供应商、软件供应商、网关开发人员以及设备供应商提供了一个开放、通用的架构,使它们能互动地开发、部署和管理服务。其软件环境基于 Sun JAVA 虚拟机,并不涉及具体的连接协议。对于任何新设备,它都能够灵活地将其纳入现有网络。可以使用 OSGi 的对象包括各种数字和模拟的机顶盒、服务网关、有线电视电缆调制解调器、消费类电子产品、 PC 、工业计算机、汽车等。

 

OSGi 体系结构

以下是一张 OSGi 的体系结构图:

从上图的层次结构可以看出, Native Operating System 层代表的是本地硬件与操作系统, Java VM 层为跨平台应用提供了可能。 而再往上,就是 OSGi framework 了。

Bundle 实际就是一个具有 jar(Java ARchive) 格式的文件,其中包含了 java class 文件和其他资源文件(比如图标,配置文件等等)。 Bundle 可以在自己的 manifest 文件中说明自己能够提供哪些 java 包,其他 bundle 如果在自己的 manifest 文件中指定了它需要这个包,那他们之间就可能产生 java 包的依赖关系,这样多个 bundle 之间就可以共享 java 包。

OSGi R4 中将功能分为几层,包括:安全层、模块层、生命周期层、服务层和实际的服务。 OSGi 的核心实现即为 OSGi 框架,它本身也是一个 OSGi Bundle

名称 ( )

职责或功能

Security (安全层)

OSGi 环境中应用的部署和管理提供更好的安全控制。

Modules (模块层)

主要负责 bundle 的安装部署,更新和卸载。

Life Cycle( 生命周期层)

Bundle 组件的安全和生命周期操作提供了 API 定义,该层位于安全层和模块层之上。

Services( 服务层 )

定义了一个与生命周期层紧密结合的组件动态交互模型。 OSGi 中的服务是实现了一个或多个 Java 接口的 Java 对象,通过将这些对象依据其实现的接口注册到服务注册表中, Bundle 组件可以发布自己的服务,查找使用服务,注册监听处理服务的状态变更等。

Actual Services( 实际的服务 )

OSGi 定义的一些标准的服务接口如日志服务( Log Service ),包管理服务( Package Admin Service )、启动级别服务( Start Level Service )、 HTTP 服务( Http Service )、配置服务( Config Admin Service )、用户管理服务 (User Admin Service) 等。

 

OSGi 容器

现在比较流行的开放源码的 OSGi 容器有以下三种 :

 

a)   Equinox 容器是参照 OSGi 规范第 4 版实现的,它构成了 Eclipse IDE 的核心—模块化的 Java 运行时;它实现了 OSGi 规范 4 中规定的必须强制实现的功能,同时,它也实现了 OSGi 规范中大部分的可选功能;

 

b) Knoflerfish OSGi 规范第 3 版和第 4 版的开源实现,它实现了 OSGi 规范规定的必须实现的功能及部分可选功能;

 

c) Apache Felix Apache 软件基金会实现的 OSGi 开源容器。

 

 


OSGi 项目实践

技术是做出来的,不是想出来的。

以下,我将使用 Equonix 作为 OSGi 容器,来做一个小项目,将一天以来学习到的知识用到具体实践之中。

便携设备越来越多,连家庭主妇身边都可能有个 PDA 或者智能手机,优秀的家庭主妇都是管帐的高手,相信做一个支出管理系统会大卖特卖。现在忽略 PDA 或是智能机用的是什么硬件配置以及接口,用 Swing 来模拟前端界面。

 

我把这个系统命名为 ExpenseManager, 下面是系统的包结构:

 

 

pratice.domain        用来放实体类

pratice.service       存放支出管理系统提供服务的接口及其实现类

pratice.uri               界面相关的类

 

完成 1.0 版时的包结构如下:



 

 

其中, Expense 是代表一条消费记录的实体类,其定义如下:

public class Expense {

   

    private int id ;           // 消费 ID

    private String date ; // 消费时间

    private String item ; // 消费项目

    private float money ;      // 消费额

   

    public String getDate() {

       return date ;

    }

    public void setDate(String date) {

       this . date = date;

    }

……// 省略其它属性 get,set 方法

}

ExpenseDB 类代表一个存储消费记录的数据库表,提供插入,检索数据,查询列名等操作,类图如下:





 

 
 
 

ExpenseManagerService 是系统的服务接口,定义系统可以向外提供的功能,在 1.0 版中只实现了增加支出记录功能,以后可逐步增加诸如,删除,修改,统记等功能。下面给出接口及其实现类代码:

 

public interface ExpenseManagerService {

    public void addExpense(Expense expense);

}

 

public class ExpenseManagerServiceImpl implements ExpenseManagerService {

    private ExpenseDB expenseDB ;

    public ExpenseManagerServiceImpl(ExpenseDB expenseDB ) {

       this . expenseDB = expenseDB ;

    }

    public void addExpense(Expense expense) {

       expenseDB .addExpense(expense);

    }

}

 

ExpenseManagerURI 类是界面类,也是 bundle 中的 Activator ,继续自 JFrame ,同时实现 BundleActivator 接口。只要在 MANIFEST.MF 中指定

Bundle-Activator: pratice.uri.ExpenseManagerURI

framework 就能通过 ClassLoader 找到 pratice.uri.ExpenseManagerURI .class 并加载后,就可以通过 newInstance() 方法创建一个 BundleActivator 的实例,然后调用 public void start(BundleContext context) 方法和 void stop(BundleContext context) 方法来管理 bundle 的生命周期。代码略。

       AddExpenseDialog 是增加支出记录的对话框。

 

MANIFEST.MF 文件内容如下:

Manifest-Version : 1.0

Bundle-ManifestVersion : 2

Bundle-Name : ExpenseManager Plug-in

Bundle-SymbolicName : ExpenseManager

Bundle-Version : 1.0.0

Bundle-Activator : pratice.uri.ExpenseManagerURI

Bundle-Localization : plugin

Import-Package : org.osgi.framework; version ="1.3.0 "

 

布署到 Equonix 容器后,执行效果见下图:




 
 

 

点击添加记录,跳出加支出记录的对话框。



 

输入数据提交后,在管理系统界面点击支出列表,罗列出支出记录。

 

为显示 OSGi 架构支持即插即用,动态部署的特性,在 1.1 版中增加统计消费额的功能,只要 执行 Equonix 框架 提供的更新命令, framework 就完成对 bundle 的升级工作。为此,对源代码进行相应修改。

ExpenseManagerService 接口增加统计方法,实现类与 ExpenseDB 类作相应修改。

 

public interface ExpenseManagerService {  

    public void addExpense(Expense expense);

    public float sumAllCost ();

}

public class ExpenseManagerServiceImpl implements ExpenseManagerService {

    private ExpenseDB expenseDB ;

    public ExpenseManagerServiceImpl(ExpenseDB expenseDB) {

       this . expenseDB = expenseDB;

    }

    public void addExpense(Expense expense) {

       expenseDB .addExpense(expense);

    }

    public float sumAllCost() {

       return expenseDB .sumAllCost();

    }

}

public class ExpenseDB {

   

    private List<Expense> expenseList ;

……// 其余代码省略

    public float sumAllCost() {

       float sum = 0;

       for ( int i = 0; i <= expenseList .size(); i++ ){

           sum += ((Expense) expenseList .get(i)).getMoney();

       }

       return sum;

    }

}

MANIFEST.MF 文件内容如下:

Manifest-Version : 1.0

Bundle-ManifestVersion : 2

Bundle-Name font-size: 10pt; color: black; font-family:

OSGi架构研究


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论