OSGI原理和实现框架总结.docx

上传人:b****6 文档编号:8925913 上传时间:2023-02-02 格式:DOCX 页数:31 大小:1.24MB
下载 相关 举报
OSGI原理和实现框架总结.docx_第1页
第1页 / 共31页
OSGI原理和实现框架总结.docx_第2页
第2页 / 共31页
OSGI原理和实现框架总结.docx_第3页
第3页 / 共31页
OSGI原理和实现框架总结.docx_第4页
第4页 / 共31页
OSGI原理和实现框架总结.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

OSGI原理和实现框架总结.docx

《OSGI原理和实现框架总结.docx》由会员分享,可在线阅读,更多相关《OSGI原理和实现框架总结.docx(31页珍藏版)》请在冰豆网上搜索。

OSGI原理和实现框架总结.docx

OSGI原理和实现框架总结

OSGI原理和实现框架总结

V1.0.0

版本

编制修改/日期

审核/日期

批准/日期

备注

1.0.0

伏红平/2011-09-15

初稿

 

目录

OSGI原理和实现框架总结1

目录2

OSGI解读3

安全层:

3

模块层:

4

生命周期层:

6

服务层:

7

服务规范:

8

Equinox8

项目主页:

8

目前发布版本:

8

遵循标准:

9

Licenses9

下载:

9

开发和调试:

9

运行:

9

Felix9

项目主页:

9

目前发布版本:

9

遵循标准:

10

Licenses10

下载:

10

开发和调试:

10

运行:

10

文档:

10

其它:

10

Knopflerfish11

官方网站:

11

目前发布版本:

11

遵循标准:

11

License11

Knopflerfish3.X中包含的组件:

12

安装Knopflerfish12

运行Knopflerfish12

创建bundles13

例子:

两个数计算服务13

设置开发调试环境:

13

接口定义:

15

接口实现:

18

获取服务:

21

测试:

24

调试:

24

导出bundles:

25

部署到equinox:

26

部署到Felix:

27

部署到Knopflerfish:

28

个人总结:

29

参考资料:

29

OSGI解读

OSGI框架从功能上分为下面几个层次:

●安全层SecurityLayer

●模块层ModuleLayer

●生命周期层LifeCycleLayer

●服务接口层ServiceLayer

安全层:

OSGi安全层是OSGi服务框架的一个可选的层。

它基于Java2安全体系结构,提供了对精密控制环境下的应用部署和管理的基础架构。

OSGi服务平台采用两种方式对代码进行校验:

●位置验证

●签名验证

模块层:

ModuleLayer定义了在OSGI框架中是怎么去按照Module的思想去开发的。

框架定义了模型化单元,称之为一个bundle。

一个bundle由java的类和其他资源组成,可以为终端用户提供功能。

通过良好定义的方式,Bundle可以和导入(importer)及导出

(exporter)Bundle之间共享Java包。

在OSGi服务框架中,bundle是仅有的需要部署的Java应用实体。

Bundle以JAR文件的方式进行部署。

 

一个bundle是一个如下的JAR文件:

●拥有提供服务所必须的资源。

这些资源可以是java的class文件,或者是其他的数据如HTML文件,帮助文件,图标文件等。

一个bundleJAR文件也可以嵌入其他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这样的OSGimanifest头,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方法可获取指定BundleID的Bundle对象,在获取到Bundle对象后可使用Bundle对象的start方法来启动Bundle,此时会调用MANIFEST.MF中的Bundle-Activator属性对应的BundleActivator类的start方法(如存在BundleActivator类),在start方法执行的过程中Bundle的状态为STARTING,当start方法执行完毕后Bundle的状态转变为ACTIVE,如start方法执行失败,Bundle的状态转变为RESOLVED。

●停止Bundle

通过BundleContext的getBundle方法可获取指定BundleID的Bundle对象,在获取到Bundle对象后可使用Bundle对象的stop方法来启动Bundle,此时会调用MANIFEST.MF中的Bundle-Activator属性对应的BundleActivator类的stop方法,在stop方法执行的过程中Bundle的状态为STOPPING,当stop方法执行完毕后Bundle的状态转变为RESOLVED,如stop方法执行失败,Bundle的状态则继续保留原状态。

即使Bundle已经停止,其export的package仍然是可以使用的,这也就意味着可以执行RESOLVED状态的Bundle中exportpackage的类。

●卸载Bundle

通过调用Bundle对象的uninstall方法可完成Bundle的卸载,此时Bundle的状态转变为UNINSTALLED。

即使Bundle已卸载,其export的package对于已经在使用的Bundle而言仍然是可用的,但对于新增的Bundle则不可使用已卸载的Bundleexport的package。

●监听Bundle的状态

在监听Bundle的状态上OSGI采用的是典型的Java中的事件机制,在OSGI中事件分为FrameworkEvent和BundleEvent两种,FrameworkEvent用于报告Framework已启动、改变了StartLevel、刷新了packages或是出现了错误;而BundleEvent则用于报告Bundle的生命周期的改变。

可通过实现BundleListener或SynchronousBundleListener来监听BundleEvent,可通过实现FrameworkListener来监听FrameworkEvent。

服务层:

ServiceLayer定义了Bundle动态协作的服务发布、查找和绑定模型,ServiceLayer

基于ModuleLayer和LifecycleLayer,使得OSGI形成了完整的动态模型。

不过ServiceLayer的定义比较简单,是一个典型的ServiceLocator模式的模型,

Service通过BundleContext完成注册和获取。

●服务的注册

可在任何时候通过BundleContext的registerService方法来完成服务的注册,和其他的服务框架一样,在OSGI中注册服务时也可以注册一个ServiceFactory的类,服务成功注册后会返回ServiceRegistration对象,通过这个对象的unregister方法可卸载服务。

 

●服务的获取

可在任何时刻通过BundleContext来获取服务,而通过BundleContext在需要的时候获取服务则可保证获取服务的动态性。

●服务的监听

通过实现ServiceListener可监听Service的状态,通过BundleContext注册监听器,在注册监听器时可增加过滤的属性,以更加准确的监听希望监听的服务的事件。

在OSGIR4中还推出了DeclarativeServices

DeclarativeServices提供了更好的服务注册、获取、监听等方式,使得其成为了OSGIR4中的重要角色,并由此替代了ServiceLayer。

DS提出了完整的Service-OrientedComponentModel(SOCM)概念,使得在Bundle

中可以按照Component+Service的方式进行开发。

Component和Service从定义上来看是差不多的,任何一个普通的Java对象都可以通过在配置文件中定义成Component,Component有下面这些作用:

●对外提供Service;

●使用其他Component提供的Service;

●交由OSGI框架管理生命周期。

通过配置文件可以把一个普通的Java对象定义为DS中的Component。

在DS中,服务的发布和获取都是通过配置文件完成。

服务的获取更像是spring中的IOC,在使用的时候由框架注入。

服务规范:

OSGI的server规范中定义了众多的服务,常用的服务:

●LogServer:

用于以日志方式记录系统操作。

●HttpServer:

要求至少实现servlet2.1规范便于开发人员基于此服务对外提供简单的http访问。

●ConfigurationAdminServer:

用于管理各bundle或其它OSGI服务的配置信息。

●DeclarativeServer:

可以实现DI方式的OSGI服务注入,并且是动态的。

●EventAdminServer:

用于实现事件方式的通知。

Equinox

项目主页:

http:

//www.eclipse.org/equinox/

目前发布版本:

3.7

2011.6.13

 

遵循标准:

OSGiRelease4,version4.2specification

实现了OSGI规范中所有方面。

Licenses

Eclipselicense

下载:

整个SDK,大概20M左右(压缩后),包含二进制文件和源码,不含文档。

官方文档提供的内容不多,基本是基于eclipse的在线文档和一些示例。

http:

//eclipse.org/equinox/documents/

开发和调试:

无需安装任何插件,直接用eclipse即可。

运行:

 在外部可以使用命令行或者下载一个launcher来启动框架。

Felix

项目主页:

http:

//felix.apache.org/site/index.html

包含很多个子项目,并不是作为单个项目开开发

目前发布版本:

Framework3.2.2

2011.5.23

遵循标准:

OSGiRelease4,version4.2specification

Licenses

ApacheLicense,Version2.0

下载:

核心框架和其它子项目的jar包被分开,每个子项目的jar都需要单独下载。

核心框架总大小只几百K,轻量级框架。

开发和调试:

●安装eclipse插件

http:

//www.ops4j.org/pax/eclipse/update/

●在eclipse中新建工程,导入下载的源文件。

运行:

框架本身非常紧凑,你只需要3个包加一个shell就可以运行了

功能需要扩展则加入其它的jar包

文档:

官方文档和例子详细,包含用户文档和开发文档,社区非常活跃。

其它:

Felix在OBR,即OSGI的bundle仓库这一块做得非常非常好了。

这一块预计在OSGIV5中发布!

除了Felix,还有两个项目是和OSGi相关的。

一个是ApacheFelixKaraf,它本身是Felix的一个子项目,但他其实是封装了Felix提供更高一层的Runtime,例如提供了JAAS。

提供了Web控制台对加入其中的bundle进行管理!

另一个是ApacheAries,目前还处于起步阶段,它作为Felix的补充,提供OSGi企业级规范,包括JPA、JDBC、JTA、JNDI等等。

 

Karaf提供了bundle的运行环境。

还可以安装一个web控制台,使用浏览器进行控制

浏览器中的控制界面

Knopflerfish

官方网站:

http:

//www.knopflerfish.org/index.html

目前发布版本:

Knopflerfish3.2isreleased!

2011.7.15

遵循标准:

OSGiRelease4,version4.2specification.

License

BSDstylelicense.

Knopflerfish3.X中包含的组件:

KnopflerfishOSGiframework-OSGiR4v4.2CoreSpecificationimplementation

KnopflerfishOSGibundles-OSGiR4v4.2ServiceCompendiumimplementation

Knopflerfishcomponents&extras-Knopflerfishbundlesandutilities

 ServiceCompendium部分没有完全实现。

安装Knopflerfish

至少java1.2.2

下载jar包直接运行即可解压得到,包含源代码,二进制文件,例子和文档。

框架默认属性设置在props.xargs文件中。

 

运行Knopflerfish

直接点击OSGI目录下framework.jar文件即可运行

或者使用命令行参数:

>cdosgi

>java-jarframework.jar

Knopflerfish提供了可视化操作界面

 

创建bundles

有三种方式创建我们自己的bundles

用Eclipse

用eclipse,需要安装eclipse插件

http:

//www.knopflerfish.org/eclipse-update/

详情参考:

KnopflerfishEclipsePlugin

用Ant

用Maven

实际开发中推荐使用eclipse插件,以便快速高效开发。

 

例子:

两个数计算服务

此示例开发调试环境基于eclipse3.5。

通过BundleContext在代码中注册和获取服务的方式不推荐使用,所以使用R4规范中的DS服务。

设置开发调试环境:

Run->runconfiguration

OSGIFramework哪里新建一个运行配置,选中右边Bundles标签,打开TargetPlatform,勾选住图中的4个bundles,其中的org.eclipse.equinox.ds为支持ds服务的bundle,另外的三个为框架运行所需bundle。

配置完成后点击run按钮,看到控制台输出如下信息表示环境配置成功。

输入ss

表示框架启动成功。

键入help可以得到帮助信息

接口定义:

在例子中,我们定义一个用于计算的接口

新建一个plug-in项目

使用标准OSGI框架

填写bundle相关的描述信息,注意,这里选择不生成Activator

点击finish,在src下面新建一个包ds.calculate,包中建一个接口Calculator

接口中只有一个方法:

packageds.calculate;

publicinterfaceCalculator

{

publicStringexcute(floatfirst,floatsecond);

}

打开META-INF文件夹下面的MANIFEST.MF文件

选择runtime,在ExportedPackages哪里导出刚才创建的包,不要忘了保存。

这时候可以查看源文件,里面包含了bundle相关信息,刚才的操作也反应到文件里

至此,我们完成了第一个bundle。

接下来我们实现这个接口。

接口实现:

新建一个plug-in项目,由于是使用DS,所以也不需要生成Activator。

这里实现一个加的操作。

完成后打开MANIFEST.MF文件,选择Dependencies,添加刚才的接口bundle。

注意保存。

新建包和类实现接口。

packageds.calculate.addserver;

importds.calculate.Calculator;

publicclassAddServerImpimplementsCalculator

{

@Override

publicStringexcute(floatfirst,floatsecond)

{

System.out.println("你正在使用加法服务:

");

returnString.valueOf(first+second);

}

}

新建文件夹OSGI-INF,在文件夹里新建文件

选中接口的实现类:

打开component.xml文件发布刚才的服务,注意这里使用的是接口。

查看源文件,类似于这个样子:

点击finish,这时候再来看MANIFEST.MF文件,多了一行:

获取服务:

新建一个plug-in项目,注意也不需要生成Activator

同样先导入必须的bundle,这里即为接口。

创建包和类来使用服务:

packageds.calculate.consumer;

importds.calculate.Calculator;

publicclassConsumer

{

privateCalculatorserver;

publicvoidprintNumber()

{

System.out.println(server.excute(10,20));

}

publicsynchronizedvoidsetServer(Calculatorserver)

{

this.server=server;

System.out.println("服务被设置!

!

");

System.out.println("使用服务!

!

");

printNumber();

}

publicsynchronizedvoidunsetServer(Calculatorserver)

{

if(this.server==server)

{

this.server=null;

}

System.out.println("服务被解设置!

!

");

}

}

新建文件夹OSGI-INF

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1