网站地图
  
  高级搜索
  首页   技术论坛   博客 派计划   产品中心   资源中心   银弹在线   商城  





OSGi R4.2 public draft中新增加的Framework launch    
#1楼
给作者发送短消息 给作者发送短消息  
查看用户其他信息
总分 42 分
财富 91 goCom币
威望 21
排名 :(
段位 新手必读
这是Lifecycle Layer中的最大改进,在之前的规范中只是简单的描述了下框架的启动和关闭,在制定了这个规范后,以后无论是启动equinox还是felix,都可采用同样的方式启动,详细的来看看,本文摘自《OSGi原理与最佳实践》。

首先来看看外部应用如何通过Framework的API来实现Framework的启动,来看张启动方法的时序图先:




这个时序图完整的说明了如何通过Framework的API来实现OSGi Framework的启动和停止:

调用FrameworkFactory的newFramework方法

所有OSGi的实现都必须实现FrameworkFactory接口,此接口中只有一个方法,即newFramework(Map configuration),外部容器在实例化FrameworkFactory实现对象上有两种做法:

A.        Class.forName(FrameworkFactory实现类).newInstance()

B.        通过Java 6中提供的ServiceLoader寻找并加载FrameworkFactory的实现类,使用方法为:

假设com.acme.osgi.Factory是FrameworkFactory的实现类,那么则在META-INF下新建services目录,在此目录下建立一个org.osgi.framework.launch.FrameworkFactory的文件,文件内容即为:com.acme.osgi.Factory,在程序中则这么编写来加载此FrameworkFactory实现类:

ServiceLoader<FrameworkFactory> sl=ServiceLoader.load(FrameworkFactory.class);

Iterator<FrameworkFactory> it=sl.iterator();

在创建了FrameworkFactory实现的实例后,就可调用newFramework方法了,newFramework方法中的Map参数为控制OSGi框架行为的一些配置项,关键的有:

org.osgi.framework.bootdelegation

配置哪些package需要从boot classloader中加载,配置的值可为com.acme.*或com.acme.services。

org.osgi.framework.executionenvironment

配置Framework执行所需的环境,例如J2SE-1.5。

org.osgi.framework.library.extensions

native code的扩展名配置,例如so,dll。

org.osgi.framework.startlevel

配置Bundle启动级别。

org.osgi.framework.storage

配置用于存储OSGi应用运行时的Bundle状态等信息的路径,当此路径不存在时,框架应负责进行创建,如创建失败则抛出异常。

org.osgi.framework.storage.clean

配置storage目录是否要清除,例如值配置为onFirstInit,意味着当Framework Bundle第一次初始化之前,storage目录将被清空,这个配置项的好处是可以控制Framework重启后是否需要根据上次运行时的状态来启动。

org.osgi.framework.system.packages

Framework的parent ClassLoader应对外export的packages。

org.osgi.framework.system.packages.extra

在上面的配置项的基础上增加了扩展属性的配置,例如:

org.osgi.framework.system.packages.extra=org.acme.foo;version=1.2

org.osgi.framework.bundle.parent

和equinox中的osgi.parentClassLoader属性的含义一样,用于控制boot classloader具体是哪个classloader,有四个可选的属性值:boot、app、ext、framework,含义和equinox完全相同。

根据需要给这些属性配置相应的值后,即可调用newFramework方法创建出Framework对象了。

调用Framework的init方法

在init方法中完成Bundle Context的创建以及Framework services的注入。

通过Framework获取BundleContext

安装Bundle

通过BundleContext.installBundle来安装需要的Bundle。

调用Framework的start方法

Framework将StartLevel service设置为指定的启动级别,从而促发已安装的所有的Bundle的resolve和启动。

调用Framework的waitForStop方法

调用此方法,等待Framework的停止运行。

按照以上说明,一个典型的基于OSGi R4.2规范的OSGi Framework的启动过程代码编写示例如下:

Map p=new HashMap();

p.put(“org.osgi.framework.storage”,System.getProperties(“user.home”)+File.separator+”osgi”);

FrameworkFactory factory=Class.forName(factoryClassName).newInstance();

Framework framework=factory.newFramework(p);

framework.init();

BundleContext context=framework.getBundleContext();

…//安装Bundles

framework.start();

framework.waitForStop();

对比Felix的启动代码,是不是觉得有点相似呢?

OSGi规范中对Framework的生命周期也做了详细的说明,图示如下:




具体来看看init、start以及stop Framework时会做哪些事情。

init

init后,需要做到以下效果:

启动事件分发处理功能;

配置好Security Manager;

StartLevel设置为指定的startlevel,默认为0;

创建可用的BundleContext对象;

所有安装的Bundles的状态均设置为INSTALLED;

Framework提供的services都可用;

Framework的状态为STARTING。

start

负责根据StartLevel启动相应的已安装的Bundle,如Bundle启动失败,则广播Framework.ERROR的事件,启动完毕后Framework的状态为ACTIVE。

stop

负责停止所有运行的Bundle,释放所有的资源,并将Framework的状态置为RESOLVED。

update

停止Framework,并给Framework.waitForStop方法返回STOPPED_UPDATE或STOPPED_BOOTCLASSPATH_MODIFIED事件值,然后应用代码应自行完成update处理。

在Framework规范中,OSGi还说明了Framework运行于多线程模式下,即所有Bundle都运行在各自的线程中,基于事件机制来响应其他Bundle的事件。

         从以上改动来看,增加的Framework章节是最大的改动,Framework规范的制定吸取了Felix以及Equinox的优点,对于统一OSGi Framework的启动方式以及行为将起到很大的作用,尤其是对于嵌入OSGi框架的应用以及需要与其他容器集成的OSGi应用而言会有很大的帮助。
 




发表回复
账号用户名   密码   登录
内容:url email imgsrc image code quote
范例 Example
bold italic underline linethrough   


 [更多...]