以下都是刚开始 Geronimo 3.0 时写在开心网上的一些笔记, 现移到此处权作备份.
Geronimo 3.0 框架重构的工作已进行大半, 说来惭愧, 我除了感叹大师们的思想和设计之外, 剩下的只有学习了, 不知何时才能与大师们煮酒论 Geronimo.
本周末, 读了一些代码, 列了一些要点, 以备以后查询所需, 并与大家共享.
1. 内核的创建.
在 OSGI 环境中, 所有的组件都已 Bundle 的形式存在, Geronimo 所有的内核类和插件也不例外, 都是在 OSGI
的框架启动后被载入的, 再无原来的 BootStrap 之类的东西了. 如今的内核的初始化, 基本 Geronimo GBean 的载入和
Geronimo 插件的加载都放到 BootActivator 中, 会在第一个 Geronimo 的 Bundle 中处理, 并将
Kernel 通过 OSGI 的 Service 对外发布.
2. 插件的读取
原来的
RepositoryConfigurationStore 想来不会再用了, 如今 config.ser 文件的读取放在
ConfigurationActivator 之中, 在 Bundle 启动时会被读取. 同时通过 ConfigurationManager 的
loadConfiguration 方法加载, 如此做目的, 一来将插件的生命周期与 Bundle 的生命周期作了映射, 二来也有机会记录了
BundleContext 引用.
3. 调用顺序
BootActivator ->
PersistentConfigurationListener -> loadConfiguration( Artifact )
-> ConfigurationActivator -> loadConfiguration (ConfigurationData)
整个调用逻辑略显冗杂, 皆因 Bundle 的生命周期与 Configuration 的生命周期交合一起所致. 前几天, 我在论坛了回了贴,
窃以为, 既然 Kernel 依旧存在, 何不区分对待, 各管各得, 省得互相映射而导致这样那样的问题, 不好之处只是 Geronimo 没有与
OSGI 像现在一样结合在一起. 结果被大师们无视了, 想来有什么问题, 抑或大师们觉得俺们都弄得差不多了, 你再提个想法, 让俺们白干了 !
以以往的经验, 前者居多, 记录在此, 今后弄明白了再添加说明, 印象会深刻一点.
下周有机会, 要看一下类载入结构和插件依赖关系的变动, 这个应该是从 OSGI 之最大获益了.
回忆了一下 Geronimo 进行 OSGI 整合之处的讨论, 当时有些还不怎么明白, 现在明朗多了.
总体上, 当时有这么些整合方案 :
一种是将 OSGI 容器以插件的形式部署于 Geronimo 中, 形式和 Web 容器, EJB 容器等一样, 部署应用时,
通过检索应用的部署信息, 若与 OSGI 相关, 则部署到 OSGI 容器中, 其他类型的还是各回各家, 各找各妈. 显而易见,
这种方式是种无痛整合, 工作量只是开发一个新的插件.
第二种方式, 就是 Geronimo 部署到 OSGI 环境中, 所有的
Geronimo 的 JAR 文件和插件均是以 Bundle 的形式存在于 OSGI 环境中, 好处自然是享受到 OSGI 的那些动态载入,
细粒度类载入器关联等. 依据 Geronimo 的 Kernel 是否存在, 这种方式又可以再做细分. Kernel 存在的情况下,
事实上也就是现在使用的方式, 首先启动内核, 之后由 ConfigurationManager 启动各个插件, 再将其加载到内核中去.
这种方式下, Geroniom Is Part Of OSGI, 整合依旧不是很彻底. 最好的自然是 Geronimo IS OSGI, 此时,
再无 Kernel, 再无 GBean, 天下大同, 皆为 Bundle. GBean 之流可以通过 blueprint 的服务来代替,
如此, Geronimo 则完全脱胎换骨了. 革命革命, 先革己命, 在此得到印证.
另外, 我在想, 现在看, OSGI
几乎成了香馍馍, 感觉你的产品要是没使用 OSGI 架构, 都不好意思和别人打招呼. 我得承认, OSGI 确实有很多吸引人的地方, 但是应用于
Java EE 的环境下, 还有许多待改进的地方, 这估计也是出了那么多 RFC 的原因, 毕竟 OSGI
之处并不是想应用于企业应用的环境中, 正如 JAVA 之处是想用来做机顶盒的开发一样, 后来在 Web 环境下确大放异彩. 在整合的过程中,
出现了很多问题, 例如之前讨论的, RMI 类载入器的问题, 扩展类路径的问题, 均未在 OSGI 中得到完美解决. 如此整合 OSGI,
想来也是配合公司新推的EBA 的编程模型, 并为 WAS 先踩踩雷.
以上内容, 均是随手而写, 是从我自己的理解和对大师的言论中推断而来, 大家看的时候自个注意.
OSGI 中 Bundle 之间的依赖关系的处理比较直白, 在一个 Bunlde 安装之后的某个时机, 对其标注依赖关系进行解析,
如果万事俱备, 设置其为 Resolved 状态, 如果不满足, 则处于 INSTALLED 状态。 这种处理方式, 与 OSGI
是一个灵活易插拔的环境有关。
而在 Geronimo 中, 可不能任其如此, 所有的 Geronimo 插件都在 geronimo-plugin.xml/config.ser 中标注了依赖关系。在启动插件时, 必需首先启动其所依赖的所有其他组件。
在之前版本中, 这些都是由 ConfigurationManager 来处理的, 插件所以依赖的无非是其他插件或者类库文件, 对于前者, ConfigurationManager 会首先启动之, 而后者, 则之间将其加入当前类载入器路径中即可。
当切换到 OSGI之后, 一切都变了 。 首当其冲的是那些类库文件, 即 JAR 文件, 它们成为了一个个 Bundle, 都有了鲜活的生命,
不可只将其放到类载入器路径中就一了百了, 需要俺们安装和启动之。 其次, 谁负责按顺启动这些插件, 之前是由
ConfigurationManager, 现在则在 DependencyManager (Bundle Extender)来处理。 究其原因,
个人感觉, 技术上不存在限制, 但从设计上而言, ConfigurationManager 管理的是 Geronimo 插件在
Geronimo 内核中的生命周期, 而在 OSGI 环境中,有 OSGI 环境中的组件处理依赖关系, 显得更自然些。(个人意见, 仅供参考)
最后记录一下 DependencyManager 的处理逻辑, 它监听了每个 Bundle 的启动, 接收到安装事件之后, 会读取 geronimo-plugin.xml 文件中的依赖关系, 并尝试启动这些依赖组件。