打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
图灵社区 : 图书 : 1.1 OSGi的定义和目标

“OSGi是什么?”这个问题非常难回答。最简单的答案是:OSGi 是Java平台的一个模块化层。当然,接下来的问题是:“模块化是什么?”这里使用模块化或多或少是从传统计算机科学意义上来说的。在计算机科学里,软件应用程序的代码被分割为表示独立内容的逻辑单元,如图1-1所示。如果软件是模块化的,你可以简化开发,并且通过强化逻辑模块的界限来提高可维护性。第2章讨论更多模块化的细节。

图1-1 模块化是指将一个大系统从逻辑上分解为较小的互相协作的部分

模块化不是新概念,早在20世纪70年代就开始流行了。OSGi技术正在遍地开花,例如,它已经被作为Eclipse IDE和GlassFish应用服务器的运行环境。为什么现在它越来越流行呢?为了更好地理解OSGi为什么越来越重要,有必要先了解一些Java在创建模块化程序时的不足。了解了这些不足,你就能明白OSGi技术为何如此重要,以及它如何帮助你。

1.1.1 Java模块化的不足

Java 以面向对象的方式提供了某种程度的模块化,但它从未考虑支持粗粒度的模块化编程。尽管因为某些Java不想去解决的问题而批评它有失公允,但是Java的成功确实给那些需要更好的模块化支持的开发者带来了困难。

Java已经发展成为构建不同领域的各类应用程序的平台,范围从移动电话到企业应用。大多数应用都需要更广泛的模块化支持,或者至少应从模块化中受益。下面就来看一下Java模块化的不足。

低层代码的可见性控制

虽然Java提供了很多控制可见性的访问修饰符(例如publicprotectedprivate和包级私有),但这些都是为了解决低层面向对象封装,而不是逻辑系统划分。Java用来划分代码。如果需要代码在多个包之间可见,那么包内的代码须声明为public(或在继承时声明为protected)。有时应用程序的逻辑结构需要特定的代码分属于不同的包,但是这也意味着任何包间依赖必须声明为public,从而让代码都可见。通常这样会暴露具体的实现细节,使后续的升级更加困难,因为用户可能已经依赖于未公开的API。

代码清单1-1以 “Hello world!”程序为例进行说明:一个包提供公开接口,另一个包提供该接口的私有实现,第三个包编写主类。

代码清单1-1 Java面向对象封装的限制

package org.foo.hello;                                          Greeting.javapublic interface Greeting {        //?简单接口  void sayHello();}------------------------------------------------------------------------------package org.foo.hello.impl;                                 GreetingImpl.javaimport org.foo.hello.Greeting;public class GreetingImpl implements Greeting {  final String m_name;  public GreetingImpl(String name) {          //?接口实现    m_name = name;  }  public void sayHello() {    System.out.println("Hello, " + m_name + "!");  }}------------------------------------------------------------------------------package org.foo.hello.main;                                         Main.javaimport org.foo.hello.Greeting;import org.foo.hello.impl.GreetingImpl;public class Main {  public static void main(String[] args) {    Greeting greet = new GreetingImpl("Hello World");        //?主函数    greet.sayHello();  }}

这段代码的作者可能打算只允许第三方程序通过Greeting接口?与该程序交互。他们在Java文档、技术教程、博客或者邮件中可能都会提及这个要求,但却无法阻止第三方使用公有构造函数?构造一个新的GreetingImpl,正如?所完成的逻辑。

你或许会说,构造函数本不应该是公有的,也不需要把程序分割到多个包中。对于这个小例子来说,这当然是没问题的。但是,在实际应用中,类级的可见性加包在保证API的一致性时略显拙劣。如果私有实现细节可以被第三方开发者访问,那么当进行升级时,你除了考虑公有接口之外,还需要关注私有实现的变化。

这个问题的根源在于,虽然Java包表面上是通过包嵌套而使其具有逻辑关系,但其实不然。人们初学Java时通常有一个误解,认为父子关系的包被赋予了特殊的可见性。其实存在嵌套关系的两个包与两个没有嵌套关系的包是相同的。包嵌套主要是为了避免命名冲突,而仅为逻辑代码划分提供了部分支持。

所有这些表明在Java语言中,你通常必须要面对下面两种选择。

  1. 为了避免暴露非公有API而把不相关的类打包在一起,以致损害程序的逻辑结构。

  2. 为了保持程序逻辑结构而使用多个包,代价就是暴露非公有API,被不同包中的类访问。

两种选择都不尽如人意。

易错的类路径概念

Java平台也会妨碍好的模块化实践,罪魁祸首正是类路径(class path)。为什么类路径会为模块化带来困难呢?最大的原因是类路径隐藏了代码版本、依赖和一致性等特性。应用程序一般由各种版本的库和组件组成。类路径不关心代码版本——只返回找到的第一个版本。即使关注代码版本,但还是无法明确描述依赖关系。建立类路径的过程是烦琐易错的,你只是不停地添加类库,直到虚拟机不再报出找不到类的错误。

图1-2表明当多个JAR文件提供指定类集的时候 “类路径困境”问题会经常发生。即使每个JAR文件已经按照一个工作单元完成编译,但当在执行时合并时,Java 类路径并不关心组件的逻辑划分。这就会导致难以预料的错误,例如:一个JAR文件的类与另一个JAR文件中不兼容的类交互时会出现NoSuchMethodError异常。

图1-2 按照在类路径中出现的顺序来合并多个包含重叠类或包的JAR文件,而没有考虑包的一致性

在由独立开发的组件构成的大型应用中,依赖同一组件不同版本的情况并不少见,例如日志或者XML解析。而类路径会强制选择某个可能并不合适的版本。更糟的是,如果类路径中有同一个包的多个版本,不论是有意或是偶然,都会被Java当做是不同的包,并按照出现的顺序隐式地融合起来。

综上所述,类路径的方式不包含任何形式的一致性检查。无论获得的是系统管理员授权使用的哪些可用类,可能都只是接近你的预期。

部署和管理支持上的不足

Java还缺少对应用部署和管理的支持。在Java中存在对多个版本的依赖时,没有简单的方法来正确部署这些代码并执行。在部署之后更新应用和组件也会面临同样问题。

考虑一下希望支持动态插件机制的常见需求。唯一能实现这个合理需求的方法就是使用类加载器,但是这种方法是低级的,且容易出错。类加载器并不是应用开发者的常用工具,但是现今的许多系统却必须使用它。一个合理定义的Java模块层能够通过明确模块定义和提高代码划分的抽象级别,提供对这些特性的支持。

在更好地理解Java模块化不足的基础上,我们可以思考一下OSGi是否是你的项目的理想解决方案。

1.1.2 OSGi能帮助你吗

除了最简单的应用程序外,几乎所有的应用程序都能够获益于OSGi提供的模块化特征,所以如果你正对是否应该了解OSGi犹豫不决,那么答案非常可能是肯定的。仍然不相信吗?在以下这些你可能遇到过的常见情况下,OSGi恰恰能够给你提供一些帮助。

  • 当启动程序时,由于类路径不正确而导致ClassNotFoundException异常。OSGi可以帮助你先确保代码满足依赖关系,然后才允许执行代码。

  • 由于类路径上一个依赖库的错误版本而导致程序执行时错误。OSGi会在要求的版本和其他约束条件方面对依赖集进行一致性检查。

  • 当模块间共享类时导致类型不一致,更加具体地说,出现了像foo instanceof Foo ==false这样令人生畏的问题。使用OSGi,你就不必担心由于层次化的类加载模式隐含的限制。

  • 将一个程序打包成逻辑上独立的JAR文件,并且只部署那些某个安装所需要的部分。这大致上阐述了OSGi的目的。

  • 将一个程序打包成逻辑上独立的JAR文件,声明哪些代码可以被其他JAR文件访问,并且强调可见性。OSGi为JAR文件提供了新一级的代码可见性,这样你就可以指定哪些对外界是可见的,而哪些是不可见的。

  • 为程序定义一个插件式的扩展机制。OSGi模块化特别适合提供强大的扩展性机制,包括支持执行时的动态性。

正如你所见,这些场景覆盖了很多用例,我们无法一一列举。OSGi简单而非侵入式的本质使得你用得越多,就发现使用它的方式越多。上文已经展示了标准Java 类路径的一些不足,现在我们该向你介绍OSGi了。 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
OSGi入门篇:模块层
深入理解<mark>OSGI</mark>:第一章 Java模块化之路
Java 6中类路径ClassPath对通配符的支持
如何理解Java 9中提到的模块化?它与OSGi是什么关系?
从 Java 9 开始,Java 就华丽的转身为微服务了…
敏捷与结构性模块化(二)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服