首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用 OSGi 应用程序开发和工作的最佳实践 (5)

用 OSGi 应用程序开发和工作的最佳实践 (5)

8. 避免拆分包和 Require-Bundle开发 OSGi bundle 时,一个最佳实践是将一个包的所有类放在一个 bundle 中。将一个包分成多个 bundle 会导致使用 Require-Bundle,从而损害使用这些 bundle 的系统的可扩展和维护程度。
原因如下
模块化系统由松耦合、高聚合模块组成,每个模块执行一个相关的逻辑功能,它们之间的界限有明确的定义。该设计目标将生成易于维护和扩展的系统。OSGi bundle 是包上的模块化。
OSGi 通过每个 bundle 声明其提供松耦合的模块,这在 OSGi 术语中称为 bundle 。这是满足运行时 bundle 提供的包的。一个 bundle 不能直接依存于一个提供相关性的 bundle;至于哪个 bundle 提供相关性由 OSGi 运行时决定,根据部署到框架的 bundle 而定。结果是提供一个特殊包的 bundle 能够被提供相同包的不同 bundle 所取代,而不改变依赖那个包的 bundle。
当在同版本中一个包被两个 bundle 导出时,将出现一个拆分,每个 bundle 提供的类集合都不相同。类可能被复制,或者更常见的是,一部分包在一个 bundle 中,而另一部分在另一个 bundle 中。
图 11.  拆分包的用户需要使用 Require-Bundle 头部图 12. 从一个 bundle 中导出的包保持高 bundle 聚合 在运行时,OSGi 将用另一个 bundle 的导出满足 Import-Package 头部指定的 bundle 的依赖性。即使这不只一个 bundle 导出包,也只有一个用于满足这种依赖性。Bundles 是 “连接” 在一起的。仅存于其他导出相同包的 bundle 中的类(导入 bundle 的包没有被连接在一起)对于导入 bundle 的类加载器是不可见的。如果导入 bundle 在运行时试图使用那些类其中之一,将抛出一个 ClassNotFoundException。因为在 OSGi 中的导入/导出 bundle 在每个包基础上只提供一种方法将一个 bundle 连接到另一个 bundle,另一个机制则需要将一个 bundle 连接到多个 bundle, 在这种拆分包的情况下工作,这可以通过使用 Require-Bundle  头部和指定输出所需包的 bundle 符号名来完成。
然而,这加强了 bundle 之间的耦合:
  • 客户端现在依赖两个(或更多)bundle 提供包。
  • 所有通过提供 bundle 导出的包现在对客户端是可见的,并且当客户端 bundle 开发一段时间以后,它将开始依赖其他包。
  • 提供包的 bundle 不再被另一个包替换,只是使用了一个不同的符号名,对所有需要他的客户端 bundle 没有更改。
将包分离成多个 bundle 从而强迫使用 Require-Bundle 头部使应用程序更紧密的耦合,维护和扩展的费用也因此更为昂贵。如果您有一个包可以分成两个 bundle,而您有不需要这两部分有高聚合性,那么您应该使用两个不同的包。
9. 在 Application-Content 头部列出包含的内容(专用于 WebSphere Application Server)
在 Enterprise Bundle Archive (EBA) 文件中包含的 Bundle 应该被列在 EBA 的 META-INF/APPLICATION.MF 的 Application-Content 头部。相关 bundle 最好存储在 bundle 存储库中,它们可用于所有的应用程序。
原因如下
在 EBA 中的 bundle 能影响应用程序的配置方法,但是只要配置正在运行,那么 bundle 对其他的应用程序是不可见的。如果 EBA 含有一个或多个依赖项 ,而在 Application-Content 中没有列出,那么这些最终可能加载到一个或多个的服务器共享 bundle 空间,作为配置的结果。这会引起潜在的问题,因为其他应用程序最终被连接到这些依赖,即使它们不依靠这些依赖来配置。在运行时这将导致意外的改变,而且很难检测出。
除了包含的内容应该被列在 Application-Content 头部这个事实外,您也应该充分意识到包含内容的功能主要为了方便您的开发而提供的 — 不推荐用于生产环境中,这个由应用程序内容组成的 bundle 可以包含在 EAB 中,也可以包含在一个 bundle 存储库中。生产环境鼓励 — 并经常强调 — 应用程序从一个 bundle 库中获取所有 bundle。这使得管理适用于生产 bundle 存储库,作为应用程序代码的唯一来源。  
对于 EBA 将自动生成 APPLICATION.MF,假如没有的话。Application-Content 将被解释为在 EAB 根目录下包含的每个 bundle。每个 bundle 的版本范围将被锁定到其精确版本,在这种情况下,没有 bundle 能被其他应用程序共享、或部署之后升级。不能访问集成开发环境的 IBM Rational® Application Developer(它提供更为直接的集成)的开发人员可能不会发现,它在没有 APPLICATION.MF 的情况下包装应用程序和导入一个含有升级内容的新应用程序资产是很方便的,而不用将每个新 bundle 安装到内部 bundle 存储库。当然,APPLICATION.MF 应该在开发周期结束之前创建。通常情况下,当您从开发通过测试移到生产环境中时,包含的内容不是很常见。在测试环境中,创建一个包含所有依赖项的 EBA 是很方便的,因此它可被安装而不用考虑目标目标服务器 bundle 存储库的状态。而对于生产环境中依据上述这些理由进行操作是不明智的。
返回列表