OSGi R4.2 public draft中新增加的Framework launch

OSGi R4.2 public draft中新增加的Framework launch

这是Lifecycle Layer中的最大改进,在之前的规范中只是简单的描述了下框架的启动和关闭,在制定了这个规范后,以后无论是启动equinox还是felix,都可采用同样的方式启动,详细的来看看,本文摘自《OSGi原理与最佳实践》。

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


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

n  调用FrameworkFactorynewFramework方法

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

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

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

假设com.acme.osgi.FactoryFrameworkFactory的实现类,那么则在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框架行为的一些配置项,关键的有:

n  org.osgi.framework.bootdelegation

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

n  org.osgi.framework.executionenvironment

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

n  org.osgi.framework.library.extensions

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

n  org.osgi.framework.startlevel

配置Bundle启动级别。

n  org.osgi.framework.storage

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

n  org.osgi.framework.storage.clean

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

n  org.osgi.framework.system.packages

Frameworkparent ClassLoader应对外exportpackages

n  org.osgi.framework.system.packages.extra

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

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

n  org.osgi.framework.bundle.parent

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

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

n  调用Frameworkinit方法

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

n  通过Framework获取BundleContext

n  安装Bundle

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

n  调用Frameworkstart方法

FrameworkStartLevel service设置为指定的启动级别,从而促发已安装的所有的Bundleresolve和启动。

n  调用FrameworkwaitForStop方法

调用此方法,等待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的生命周期也做了详细的说明,图示如下:


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

n  init

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

启动事件分发处理功能;

配置好Security Manager

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

创建可用的BundleContext对象;

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

Framework提供的services都可用;

Framework的状态为STARTING

n  start

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

n  stop

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

n  update

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

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

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

你可能感兴趣的:(OSGi R4.2 public draft中新增加的Framework launch)