关于OSGI中的Felix热插拔技术

OSGI介绍
OSGI的全称是Open Service Gateway Initiative,即开放服务网关。OSGI是基于模块(Bundle)驱动的,每个模块都有属于自己的classpath和类加载器,模块之间通过包暴露和引入进行关联,每个模块有着自己独立的生命周期,我们可以动态地对模块进行加载、卸载、更新。如此看来,OSGI可以用一句话描述,就是一个为Java提供的动态模块化的系统。
Idea创建OSGI工程(简单整理一下)

  1. File -> New -> Project,选择Java,点击Next,创建一个空工程。一直next,填写项目名称,比如osgi_test。
  2. 分别创建api、server、client三个OSGI模块。创建模块时勾选OSGI作为开发环境,Use library从下载的Equinox解压的目录下的plugins目录中选择org.eclipse.osgi_3.16.100.v20201030-1916。我的版本为4.18。
  3. java热插拔 java模块化热插拔_bundle

  4. 创建完模块之后,打开idea的Setting,在Languages & Frameworks找到OSGI,点击。添加Equinox,Home directory选择刚才解压的Equinox目录。
  5. 工程的结构如图:

java热插拔 java模块化热插拔_java热插拔_02

  1. 配置每个各模块OGSI
    ①、Idea—File—Project Structure—Modules。点击api,client,server下面的OSGI,进入Manifest Generation进行配置。
    ②、api模块配置,导出接口定义所在包osgi.demo.api(Additional properties是bundle的相关属性配置的地方)。
    ③、server模块配置,配置HelloServerBundle类作为该bundle的启动类。
    ④、client模块配置,配置HelloClientBundle类作为该bundle的启动类。

osgi启动配置并运行,选择Edit Configurations,添加OSGI Bundles。
client模块调用了server的服务,按照依赖关系,server模块需要先启动,把服务注册在osgi框架中,client模块才能调用到,Start level是用来定义bundle模块的启动优先级,值越小,启动优先级越高。
Framework start level是整个osgi框架的启动级别,也就是整个项目的启动级别,大于这个值的bundle模块是不会被启动的。如果这个值为1,client模块的启动级别为2,client模块是不会被启动的

如图:

java热插拔 java模块化热插拔_类加载器_03

  1. 运行结果:

java热插拔 java模块化热插拔_osgi_04

Felix

  1. 首先下载Felix,进入Felix目录,打开cmd窗口,启动执行 java -jar ./bin/felix.jar
  2. 几个简单的命令:
    lb:查看当前启动Felix的bundle
    stop 0: 停止Felix框架
    安装Felix的bundle(client.jar)是需要bundle的绝对路径,执行命令install file:/file_path
    install file:/D:/code/osgi_test/out/production/client.jar
    start bundleID: 启动bundle命令
    stop bundleID: 停止bundle命令
    update bundleID: 重新加载某个 bundle
    uninstall bundleID:卸载某个 bundle
  3. 项目启动如图:

java热插拔 java模块化热插拔_java_05

OSGI中模块的生命周期和状态
OSGI 类加载器并不遵循 Java 的双亲委派模型,OSGi 为每个 bundle 提供一个类加载器,该加载器能够加载 bundle 内部的类和资源,bundle 之间的交互是从一个 bundle 类加载器委托到另一个 bundle 类加载器,所有 bundle 都有一个父类加载器。

INSTALLE:成功安装Bundle。
RESOLVED :所有Bundle需要的Java类可用。这个状态标志着 bundle已经是启动就绪或者是已经停止。
STARTING: 正在启动Bundle。调用了Bundle激活器的start方法,而且还没有从方法中返回。
ACTIVE :Bundle已经启动完毕,正在运行中。
STOPPING :正在停止Bundle。调用了Bundle激活器的stop方法,而且还没有从方法中返回。
UNINSTALLED :Bundle已经卸载完毕,不能进入其他状态。

java热插拔 java模块化热插拔_osgi_06