这篇文章是自己参照 Apache Felix 官网 参考指导手册上的学习步骤书写的篇目,算不上原创的内容,权当时自己写的一些学习笔记,当然其中内容也不是完全参照官网上说的来写,一些部分按照自己的理解做了些修改,更加便于自己理解,对于文中一些地方读者觉得不明白或者笔者理解错误的地方,欢迎各位读者指正,互相学习!
本文适合对于Java 一些高级特性比较了解,对于项目模块化热部署有了解,理解 OSGI【百度百科】是一个什么规范的读者阅读,对于刚学习了 Java 的一些初级读者,本人就不建议学习这些内容了。
只需要知道这个框架是 OSGI 规范的一个由 Apache 实现的框架就可以了。
因为此学习笔记的例子来自于官网,代码都比较简单、易懂,因此我们直接使用最原始的 Java 编写方式就可以了。
- bin --> 里面就一个 felix.jar, 不用说,就是 felix 的启动文件了。
- bundle --> felix 启动之后默认加载模块的目录。
- conf --> 默认里面就一个 config.properties, 一看就知道是配置文件目录。
######################## 以下目录为新建的学习代码目录 #################################
- source --> 源码目录
注意必须使用上面的命令执行,因为 felix.jar 默认会在当前当前运行目录的 bundle 文件夹内加载启动所需的 bundle,config 目录下的 config.propeties 和 system.properties 里面加载环境变量,如果将其他目录作为启动根目录,该目录下不存在 felix 启动所需信息,启动就会有问题,当然这些配置可以在启动的时候以参数的方式配置,但是还是推荐上面的方式启动。
项目启动起一次启动的时候回在启动目录下创建一个 felix-cache 的目录,用于存放框架运行过程产生的数据,当然该目录可以在启动的时候配置,使用 java -jar ./bin/felix.jar <felix-dir> 即可。
默认felix-cache的更目录可以配置在./conf/config.properties 文件中,具体配置为“felix.cache.rootdir=${user.home}/.felix”,这样在在我们使用 java -jar ./bin/felix.jar 启动 felix 的时候,会在当前用户目录下启动一个.felix 文件夹, 并且以.felix文件夹作为 felix-cache 目录的根路径,框架在启动的时候会读取名称为 user.home 的系统属性替换 ${user.home} 的位置。
g! lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.0)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.0)
3|Active | 1|Apache Felix Gogo Runtime (0.6.0)
4|Active | 1|Apache Felix Gogo Shell (0.6.0)
在讲解下面的内容之前,首先让我们来明确一个概念,什么是 shell【百度百科】! 和 Felix 框架交互的主要方式是使用 Apache Felix Gogo Shell,当框架启动之后,使用 helo 命令可以查看所有可以使用的命令,使用 help <command-name> 可以查看指定命令的帮助信息。
小贴士:
在 Gogo 中,命令的名称由两部分组成--<scope>:<name>。类似于Java 使用全类名的方式避免命名冲突,如果再所有的命令中 <name> 部分是唯一的,可以直接使用 <name> 部分作为命令输入执行,如 help, 否则,则必须使用 <scope>:<name> 的方式输入命令执行。
使用 felix:install 命令可以安装 bundle, 至于详细的说明会在下一章中介绍。我们可以使用 felix:lb 查看当前系统安装的所有 bundle 信息, 可以使用 stop 0 停止系统核心 bundle,框架也会相应的关闭,任何已经被安装的 bundle 在框架启动的使用都会被重新加载(同时也会被启动)。
bundle 是 OSGI 框架中的组件,bundle 是一个简单的 Jar 包,其中包含了 MANIFEST.MF 文件和一些其他的文件: class 文件、嵌入式的 jar 文件、原生代码、资源文件组成。一个 bundle 可能提供一些供用户使用的方法,也可能是实现特定的服务以供其他的 bunlde 使用;bundle 只有导出的服务和包才能够被其他 bundle 使用。
Felix 主要由三个 bundle 组成,位置在 ./bundle 目录下,这三个 bundle 包括: Gogo Runtime(提供核心命令处理支持的功能),Gogo Shell(提供基于文本的Shell和用户交互),Gogo Command(提供基础的设置命令),另外还有 Bundle Repository(为Bundle提供仓库服务,类似于 Maven 仓库的概念),Bundle Repository 使访问其他 Bundle 变得非常容易,Bundle Repository 可以使用 obr:* 范围内的命令使用,具体使用方式可以在 Apache Felix OSGi Bundle Repository 找到更多帮助信息。
在安装 bundle 之前,我们需要重点学习如何将一个 bundle 安装到 felix 中!安装主要分为两个步骤,第一是安装、第二是运行,我们可以使用 felix:install 命令安装 bundle,假设我们需要安装的 bundle 名称为 bundle.jar,位置为 /path/to/bundle/bundle.jar, 则安装命令如下:
felix:install file:/path/to/bundle/bundle.jar
当 bundle 安装成功之后,使用 felix:start <bundle-ID> 命令启动安装好的 bundle,那我们应该如何获取到安装好的 bundle 的 <bundle-ID> 呢?答案就是使用 felix:lb 命令查看所有已经安装好的 bundle,如下:
g! install file:/path/to/bundle/bundle.jar
g! lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.0)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.0)
3|Active | 1|Apache Felix Gogo Runtime (0.6.0)
4|Active | 1|Apache Felix Gogo Shell (0.6.0)
5|Installed | 1|Example Bundle (1.0.0)
g! start 5
Hello from Bundle 5.
g!
从上面可以看出,我们刚安装好的名字为 bundle.jar 的 bundle,其 bundle-ID 为 5,我们使用 start 5 (别忘了 felix:start 可以是使用 start 命令简介表示哦)命令启动 bundle,下面输出的 Hello from Bundle 5 是 bundle 在启动的时候输出的信息。
bundle 启动之后,我们可以使用 felix:stop <bundle-ID> 命令停止该 bundle 的运行,使用 felix:uninstall <bundle-ID> 命令卸载安装的 bundle。另外 bundle 的“安装”和“启动”两个步骤我们可以通过 felix:start <bundle-URL> 的方式一步到位,例如上述名称为 bundle.jar 的 bundle 的安装我们可以使用如下的命令安装、启动:
felix:start file:/path/to/bundle/bundle.jar
我们可以使用 felix:update <bundle-ID> 的方式重新加载某个 bundle,注意:felix:update 和 felix:uninstall 命令被执行之后都会立即生效,但是被更新或者卸载的 bundle 导出的接口如果被其他 bundle 引用,则其他接口依然有效,这些引用将会一直存在,直至框架停止或者使用 PackageService 服务刷新,看上去比较麻烦,于是 Felix 框架为我们提供了简单的方式实现前述的功能,即 refresh 命令,这样的实现在 OSGI 规范中是有据可循的。
这部分看懂了文档,不知道如何操作,这里就不写了,大家可以参考 官方指导。
如果我们希望修改框架启动默认加载 bundle 的位置,我们可以使用如下的方式配置
java -jar ./bin/felix.jar -b /path/to/dir
更多细节参考 官方指导。
Felix 框架的整个生命周期中的默认行为都可以通过配置文件的方式修改,默认的配置文件位置为 conf/config.properties 文件,该文件支持 Java 标准的配置文件格式。
Felix 框架运行过程中,系统属性可以通过 conf/system.properties 文件配置,此种配置系统属性的方式可以简化我们对于框架运行过程中属性的修改。虽然系统属性对于框架本身并无影响,但是框架启动程序在启动框架的时候会将 conf/system.properties 配置文件下所有的属性读取到系统配置映射中。
在框架启动的过程时,可以通过配置 felix.config.properties 和 felix.system.properties 两个属性修改 config.properties 和 system.properties 两个配置文件的默认目录,如下:
java -Dfelix.config.properties=file:/home/rickhall/config.properties -jar bin/felix.jar
在运行过程中我们都可以在 bundle 中使用 context.getProperty("key") 获取配置或者系统属性信息,如果系统属性和配置属性中出现了两个同名属性,则配置属性值会覆盖系统属性中的同名属性值,更多配置属性的信息可以在 Apache Felix Framework Configuration Properties 中找到详细帮助信息,Felix 框架默认存在 conf/config.properties 文件。
在 config.propeties 中配置的的属性值可以使用 ${<property>}/foo 的方式,<property> 表示系统配置中的信息,启动程序在解析的时候会自动将 <property> 解析为系统配置文件中该键对应的值。
更多详情请参考 官方指导。