OSGI 生命周期
阅读原文时间:2023年07月08日阅读:2

1 生命周期管理

对于非模块化应用,生命周期将应用作为一个整体来操作;

而对于模块化应用,则可以以细粒度的方式来管理应用的某一个独立部分。

OSGi生命周期层有两种不同的作用:

  • 在应用程序外部,定义了对bundle生命周期的相关操作。OSGi生命周期层允许在执行时,从外部安装、启动、更新、停止、卸载不同的bundle,进而定制应用的配置。
  • 在应用程序内部,定义了bundle访问其执行上下文的方式,为bundle提供了一种与OSGi框架交互的途径以及一些执行时的便利条件。

安装:jar下载时被安装;

执行:用户启动JVM时被执行;(双击)

更新:替换jar文件;

移除:删除jar文件。

生命周期由servlet容器管理

安装:通过容器的特定进程被安装;

执行:servlet容器调用各种生命周期API,如Servlet.init()、Servlet.destroy();

更新:替换WAR文件;

移除:通过容器的特定进程被移除。

2 生命周期层的三个接口

如果要对一个bundle进行生命周期管理,必须要在这个bundle中声明一个bundle激活器类,实现org.osgi.framework.BundleActivator接口。这个接口为bundle提供了挂接到生命周期层的钩子,同时自定义bundle在启动或停止时执行的操作。

还必须在MANIFEST.MF中描述该bundle激活器:

Bundle-Activator: org.alpha.MyActivator  

注意:并非所有bundle都需要一个激活器。只有当明确需要与OSGI API进行交互,或者需要执行自定义的初始化/销毁动作时,才必须要激活器。

  • 当bundle被安装并启动以后,框架将构建相应的BundleActivator的一个实例,触发BundleActivator.start()

  • 当bundle停止后,框架会调用BundleActivator.stop();stop()方法应该取消start()中执行过的所有操作。

public   interface  BundleActivator {  
   public   void  start(BundleContext context)  throws  Exception;  
   public   void  stop(BundleContext context)  throws  Exception;  
}  

BundleActivator的两个方法都接受一个BundleContext对象作为参数。BundleContext是bundle与OSGi framework通信的桥梁。BundleContext可以做的事有:

  • Look up system-wide configuration properties;
    ——获取系统properties
  • Find another installed bundle by its ID;
    ——通过ID查询已安装的其他bundle
  • Obtain a list of all installed bundles;
    ——获取已安装的bundle列表
  • Introspect and manipulate other bundles programmatically: start them, stop them, un-install them, update them, etc;
    ——在程序中操作其他bundle(启动、停止、卸载、更新)
  • Install new bundles programmatically; 
    ——在程序中安装新bundle
  • Store or retrieve a file in a persistent storage area managed by the framework; 
    ——往框架管理的持久化存储区中存储或查询文件
  • Register and unregister bundle listeners, which tell us when the state of any bundle in the framework changes; 
    ——注册bundle listener,监听bundle状态的改变
  • Register and unregister service listeners, which tell us when the state of any service in the framework changes 
    ——注册service listener,监听service状态的改变
  • Register and unregister framework listeners, which tell us about general framework events.
    ——注册framework listener,监听一般框架事件

每个已激活的bundle都会接收到属于自己的BundleContext对象,该对象不能在bundle直接自由传递!

只有当bundle处于激活状态(从start()开始,到stop()结束),BundleContext对象才是有效的。其他状态下调用该对象,会抛出异常。

public  interface  BundleContext {  
  String getProperty(String key);  
  Bundle getBundle();  
  Bundle getBundle( long  id);  
  Bundle[] getBundles();  
  
  Bundle installBundle(String location)  throws  BundleException;  
  Bundle installBundle(String location, InputStream input)  throws  BundleException;  
  
   void  addBundleListener(BundleListener listener);  
   void  removeBundleListener(BundleListener listener);  
   void  addFrameworkListener(FrameworkListener listener);  
   void  removeFrameworkListener(FrameworkListener listener);  
}  

对于每个已安装的bundle,框架都会相应地创建一个逻辑上代表他的Bundle对象。Bundle接口定义了一系列API,用于管理已安装bundle的生命周期。

public interface Bundle {  
   BundleContext getBundleContext();  
   long  getBundleId();  
   Dictionary getHeaders();  
   int  getState();  
   String getSymbolicName();  
   Version getVersion();  
  
   void  start( int  options)  throws  BundleException;  
   void  start()  throws  BundleException;  
   void  stop( int  options)  throws  BundleException;  
   void  stop()  throws  BundleException;  
   void  update(InputStream input)  throws  BundleException;  
   void  update()  throws  BundleException;  
   void  uninstall()  throws  BundleException;  
}  

注意:BundleId=0的bundle表示OSGi框架本身,称为系统bundle
当停止系统bundle时,它会首先停止其他bundle,然后才将自身完全关闭;以友好的方式关闭框架。

3 生命周期状态

调用BundleContext.installBundle()后,会创建一个INSTALLED状态的bundle

如果其所依赖的所有bundle都存在,即解析成功,转到RESOLVED状态

注意:不能直接从INSTALLED --> STARTING

当开始执行BundleActivator.start(),则处于STARTING状态;

注意:这是一个瞬时状态

当执行BundleActivator.start()成功,则转到ACTIVE状态;

如果抛出异常,则回到RESOLVED状态。

当开始执行BundleActivator.stop(),则处于STOPPING状态;

如果执行成功,则转到RESOLVED状态。

注意:这是一个瞬时状态

INSTALLED状态的bundle可以被卸载,转到UNINSTALLED状态;

如果卸载一个ACTIVE状态的bundle,则框架会首先自动停止该bundle,使其转到RESOLVED状态;然后再卸载之前,将其状态转为INSTALLED。

Although the UNINSTALLED state is shown here, we can never see a bundle in that state, and an UNINSTALLED bundle cannot

transition to any other state. Even if we reinstall the same bundle JAR file, it will be considered a different bundle by the framework, and assigned a new bundle ID. 

刷新或更新一个bundle,将使其状态退回INSTALLED状态!

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章