OSGI Module&lifecycle
OSGI概念中主要分为了Bundle和Service,可以认为Bundle是一个模块的管理器,主要是通过BundleActivator管理模块的生命周期,而Service则是这个模块可暴露对外的服务对象,这里体现了OSGI和传统的Plugin Framework不同的一个地方,管理和静态结构分开,在OSGI中通过在manifest.mf文件中增加一些内容来发布Bundle,在其中描述了Bundle的提供商、版本、唯一ID、classpath、暴露对外的包、所依赖的包;每个Bundle拥有自己的ClassLoader以及context,通过context可进行服务的注册、卸载等,这些操作都会通过事件机制广播给相应的其他的Bundle;一般来说都为通过在Bundle中编写初始需要注册的服务的方法来完成Bundle可供外部使用的服务的暴露功能;如需要调用其他Plugin提供的服务可通过context的getServiceReference先获取Service的句柄,再通过context.getService(ServiceReference)的方法获取Service的实体。
前一段时间对osgi的service层做了介绍,下面介绍module和lifecycle层,在这里主要介绍lifecycle
系统框架对bundle的生命周期进行了管理。
osgi生命周期的管理,覆盖到bundle的安装,启动,停止,更新,卸载,和监控这么一个过程。
Bundle的生命周期
下面是bundle的lifecycle的类图
下面详细介绍bundle的几个对象
l Bunlde 标识
Identifier
Location
symbolicName
l bundle的状态
状态转换图
ü bundle的安装一般有两种方式:
通过另外一个bundle的bundlecontext来完成
通过命令行的形式(比如系统bundle一般是这样的)来完成的
ü Bundle的解析(一般是在启动过程中完成的)
根据bundle的定义,创建基于版本的module(ModuleDefinition,ContentLoader,Wire)
ü Bundle的启动,由该bundle的调用start api来完成的
这里包含创建该bundle的上下文(BundleContext)
创建该bundle的activator,可以在activator里进行与该bundle相关的service的注册,bundlelistener,servicelistener ,frameworklistener的注册以及安装其他的bundle.等.
是否要立即触发该activator,需要根据该bundle的activator policy来决定;在用bundle获取resource的时候,采取解析bundle,才创建该bundle的classloader和activate该bundle。这样能节省启动的时间,实现了懒加载。
下图描述了bundle的启动过程中的状态变化
ü Bundle的更新
Bundle的更新,是从一个版本到另一个版本的迁移过程
流程如下:
1. 检查bundle的状态
如果是uninsalled,抛出异常
2. ,但是不改变持久化的状态Stop bundle
3. 版本的修订
4. 更改bundle的时间戳,状态设置成installed
5. 发送unresolved事件给bundle
6. 把该bundle的老的module做一个removal标记,表示不可用
7. 发送updated事件给bundle
8. 启动(start)bundle
ü Bundle的停止
1. 把bundle的持久化状态设置成inactive
2. 检查bundle的状态
如果状态是Installed,Resolved,就返回
如果是uninstalled,抛出异常
如果是starting,stopping,抛异常
如果ACTIVE,把bundle的状态设置成stopping,发stopping事件跟响应的bundle
3. 调用该bundle的activator的stop操作,清理分配的资源
4. 清除bundle的上下文
清理该bundle注册的service
释放该bundle用到的service
删除该bundle注册的listener
5. 该bundle的状态返回到resolved状态
6. 发stopped事件给该bundle
ü Bundle的卸载
1. Stop bundle
2. 把该bundle从缓存中删除
3. 把该bundle放入uninstall 类别中
4. 该bundle状态设置成uninstalled
5. 触发bundle的uninstall事件
6. 看是否有以来该bundle的module,如果没有则垃圾回收
Listener和事件机制
关于这一部分功能和用法已在上一篇service层里已经做了介绍,这里只做一下简单的罗列
ü Framework
FrameworkListener:
注册时间:
触发时间:
作用:OSGI environment
FrameworkEvent: type,bundle,throwable
ü Bundle
BundleListener
注册时间:
触发时间:
作用:a bundle lifecycle change.
BundleEvent: Bundle,type
ü Service
ServiceListener
注册时间:
触发时间:
作用:a service lifecycle change.
ServiceEvent:serviceReference ,type
资源 |
事件类型 |
触发时机 |
Framework |
STARTED |
Framework启动完成
Framework has started after all installed bundles that are marked to be started have been started and the Framework has reached the intitial start level. |
ERROR |
There was an error associated with a bundle. |
PACKAGES_REFRESHED |
Framework has completed the refresh packages operation initiated by a call to the PackageAdmin.refreshPackages method. |
STARTLEVEL_CHANGED |
the Framework has completed changing the active start level initiated by a call to the StartLevel.setStartLevel method. |
WARNING |
There was a warning associated with a bundle. |
INFO |
There was an informational event associated with a bundle. |
Bundle |
INSTALLED |
The bundle has been installed. |
STARTED |
The bundle has been started. |
STOPPED |
The bundle has been stopped. |
UNINSTALLED |
The bundle has been uninstalled. |
RESOLVED |
The bundle has been resolved. |
UNRESOLVED |
The bundle has been unresolved. |
STARTING |
The bundle is about to start. |
STOPPING |
The bundle is about to stop. |
Service |
REGISTERED |
This service has been registered. |
MODIFIED |
The properties of a registered service have been modified. |
UNREGISTERING |
This service is in the process of being unregistered.
If a bundle is using a service that is UNREGISTERING , the
bundle should release its use of the service when it receives this event.
If the bundle does not release its use of the service when it receives
this event, the Framework will automatically release the bundle's use of the service while completing the service unregistration operation. |
|
|
资源的查找
几点说明
系统启动时候,会把所有职责的关联关系wire起来
并且创建核心的查找资源policy
还有就是有的module可以放在resolve阶段可以放到查找资源的时候进行,实现懒加载的功能
1.查找资源的核心类,分发中心,所有的调度逻辑都在这里
2.所有的资源查找都代理到该核心类,有点象代理的方式
3.module的修改,这里会实时的得到更新(通过注册listener)
资源的查找:在本bundle的classloader范围内,进行class的查找,资源加载的顺序可以参见规范
下面是类查找的类图
该bundle的Classloader在bundle的resolve阶段就创建好了
关于bundle的说明定义中的import export详见规范
系统Bundle的启动过程
1.系统bundle由框架启动,并且只启动一次
2. 创建服务的注册中心,该中心作为各种事件的分发场所。
3. 创建核心的查找资源的policy,加入resolver listener到该policy,可以在module解析后,得到通知更新bundle的状态
4. 初始化事件分发器
5. 在加载其他的bundle之前,创建系统的bundle负责容器相关的service,resolve系统bundle,创建系统bundle的activator,创建bundle的上下文,并触发activator
6. 安装其他的bundle
7 触发系统bundle的started事件,标志系统bundle启动完成
8. 触发框架的started时间,标志框架启动完成