Eclipse体系结构介绍(二)

6.2 Runtime, RCP and Robots

6.2.1 运行

Eclipse 3.0可能是最重要的Eclipse版本之一,因为在此发布周期中发生了重大更改。在3.0之前的Eclipse架构中,Eclipse组件模型由可以以两种方式相互交互的插件组成。首先,他们可以通过在plugin.xml中使用requires语句来表达它们的依赖关系。如果插件A需要插件B,插件A可以看到B中的所有Java类和资源,尊重Java类可见性约定。每个插件都有一个版本,他们还可以指定其依赖项的版本。其次,组件模型提供了扩展和扩展点。从历史上看,Eclipse提交者为Eclipse SDK编写了自己的运行时来管理类加载,插件依赖关系以及扩展和扩展点。

Equinox项目是作为Eclipse的新孵化器项目创建的。 Equinox项目的目标是将Eclipse组件模型替换为已存在的组件模型,并为动态插件提供支持。正在考虑的解决方案包括JMX,Jakarta Avalon和OSGi。 JMX不是一个完全开发的组件模型,因此认为不合适。雅加达阿瓦隆没有被选中,因为它似乎失去了作为一个项目的势头。除技术要求外,考虑支持这些技术的社区也很重要。他们是否愿意合并特定于Eclipse的更改?它是否积极开发并获得新的采用者? Equinox团队认为围绕他们最终技术选择的社区与技术考虑同样重要。

在研究和评估可用的替代方案之后,提交者选择了OSGi。为何选择OSGi?它有一个用于管理依赖关系的语义版本控制方案。它提供了JDK本身缺乏的模块化框架。必须显式导出其他bundle可用的包,并隐藏所有其他包。 OSGi提供了自己的类加载器,因此Equinox团队不必继续维护自己的类。通过标准化在Eclipse生态系统之外更广泛采用的组件模型,他们认为它们可以吸引更广泛的社区并进一步推动Eclipse的采用。

Equinox团队感到很自在,因为OSGi已经拥有一个现有且充满活力的社区,他们可以与该社区合作,帮助包含Eclipse在组件模型中所需的功能。例如,当时,OSGi仅支持包级别的列表需求,而不是Eclipse所需的插件级别。此外,OSGi还没有包含片段的概念,这是Eclipse为现有插件提供平台或环境特定代码的首选机制。例如,片段提供了用于处理Linux和Windows文件系统的代码以及提供语言翻译的片段。一旦决定继续使用OSGi作为新的运行时,提交者需要一个开源框架实现。他们评估了Apache Felix的前身Oscar和IBM开发的服务管理框架(SMF)。当时,奥斯卡是一个部署有限的研究项目。 SMF最终被选中,因为它已经用于运输产品,因此被认为是企业准备好的。 Equinox实现用作OSGi规范的参考实现。

还提供了兼容性层,以便现有插件仍可在3.0安装中运行。要求开发人员重写他们的插件以适应Eclipse 3.0底层基础架构的变化,这将阻碍Eclipse作为工具平台的势头。 Eclipse消费者的期望是该平台应该继续工作。

通过切换到OSGi,Eclipse插件被称为捆绑包。插件和捆绑包是相同的:它们都提供模块化的功能子集,用清单中的元数据描述自己。以前,plugin.xml中描述了依赖项,导出的包以及扩展和扩展点。随着向OSGi包的迁移,扩展和扩展点继续在plugin.xml中描述,因为它们是Eclipse概念。其余信息在META-INF / MANIFEST.MF中描述,OSGi的捆绑清单版本。为了支持此更改,PDE在Eclipse中提供了一个新的清单编辑器。每个包都有一个名称和版本。 org.eclipse.ui包的清单如下所示:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.ui; singleton:=true
Bundle-Version: 3.3.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.ui.internal.UIPlugin
Bundle-Vendor: %Plugin.providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.ui.internal;x-internal:=true
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
 org.eclipse.swt;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.jface;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.ui.workbench;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.core.expressions;bundle-version="[3.3.0,4.0.0)"
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0, J2SE-1.3

从Eclipse 3.1开始,清单还可以指定捆绑所需的执行环境(BREE)。执行环境指定运行包所需的最小Java环境。 Java编译器不了解bundle和OSGi清单。 PDE提供用于开发OSGi包的工具。因此,PDE解析bundle的清单,并为该bundle生成类路径。如果在清单中指定了J2SE-1.4的执行环境,然后编写了一些包含泛型的代码,则会在代码中告知编译错误。这可确保您的代码符合您在清单中指定的合同。

OSGi为Java提供了模块化框架。 OSGi框架管理自描述包的集合并管理它们的类加载。每个捆绑包都有自己的类加载器。通过检查清单的依赖关系并生成可用于bundle的类路径来构造bundle可用的类路径。 OSGi应用程序是捆绑包的集合。为了完全接受模块化,您必须能够以可靠的格式为消费者表达您的依赖关系。因此,清单描述了此捆绑包的客户端可用的导出包,这些包对应于可供使用的公共API。使用该API的捆绑包必须具有他们正在使用的包的相应导入。清单还允许您表示依赖项的版本范围。查看上面清单中的Require-Bundle标题,您将注意到org.eclipse.ui所依赖的org.eclipse.core.runtime包必须至少为3.2.0且小于4.0.0。

Eclipse体系结构介绍(二)_第1张图片

                  图6.4:OSGi Bundle生命周期

OSGi是一个动态框架,支持bundle的安装,启动,停止或卸载。如前所述,延迟激活是Eclipse的核心优势,因为插件类在需要之前不会加载。 OSGi包生命周期也支持这种方法。启动OSGi应用程序时,捆绑包处于已安装状态。如果满足其依赖关系,则bundle将更改为已解析状态。解决后,可以加载和运行该包中的类。起始状态表示根据其激活策略激活捆绑包。一旦激活,捆绑包处于活动状态,它可以获取所需的资源并与其他捆绑包进行交互。当捆绑包执行其激活器停止方法以清除活动时打开的任何资源时,捆绑包处于停止状态。最后,可能会卸载一个bundle,这意味着它无法使用。

随着API的发展,需要有一种方法来向消费者发出变化信号。一种方法是在清单中使用捆绑包和版本范围的语义版本控制来指定依赖项的版本范围。 OSGi使用四部分版本控制命名方案,如图6.5所示。

Eclipse体系结构介绍(二)_第2张图片 

                图6.5:版本控制命名方案

使用OSGi版本编号方案,每个包都有一个唯一的标识符,包括名称和四部分版本号。 id和版本一起表示消费者的唯一字节集。根据Eclipse约定,如果您对包进行更改,则版本的每个段都向使用者表示正在进行的更改类型。因此,如果要表明您打算破坏API,则增加第一个(主要)段。如果您刚刚添加了API,则会增加第二个(次要)细分。如果您修复了一个不影响API的小错误,则第三个(服务)段会增加。最后,增加第四个或限定符段以指示构建标识源控制存储库标记。

除了表示bundle之间的固定依赖关系之外,OSGi中还有一种称为services的机制,它提供了bundle之间的进一步解耦。服务是具有一组在OSGi服务注册表中注册的属性的对象。与Eclipse在启动期间扫描捆绑包时在扩展注册表中注册的扩展不同,服务是动态注册的。使用服务的bundle需要导入定义服务契约的包,框架从服务注册表确定服务实现。

与Java类文件中的main方法一样,定义了一个特定的应用程序来启动Eclipse。 Eclipse应用程序使用扩展定义。例如,启动Eclipse IDE本身的应用程序是org.eclipse.ui.ide.workbench,它在org.eclipse.ui.ide.application包中定义。


    
      
         
         
      
  

 Eclipse提供了许多应用程序,例如运行独立帮助服务器,Ant任务和JUnit测试的应用程序。

6.2.2 富客户端平台(RCP)

在开源社区工作最有趣的事情之一是人们以完全意想不到的方式使用该软件。 Eclipse的最初目的是提供一个平台和工具来创建和扩展IDE。但是,在3.0版本发布之前,bug报告显示社区正在使用平台捆绑包的一部分并使用它们来构建富客户端平台(RCP)应用程序,许多人都认为这些应用程序是Java应用程序。由于Eclipse最初是以IDE为中心构建的,因此必须对这些bundle进行一些重构,以便用户社区更容易采用这个用例。 RCP应用程序不需要IDE中的所有功能,因此几个捆绑包被拆分为较小的捆绑包,社区可以使用这些捆绑包来构建RCP应用程序。

野外RCP应用的例子包括使用RCP来监测NASA在喷气推进实验室开发的Mars Rover机器人,Bioclipse用于生物信息学的数据可视化,以及荷兰铁路用于监测列车性能。贯穿其中许多应用程序的共同主题是这些团队决定他们可以使用RCP平台提供的实用程序,并专注于在其上构建专用工具。他们可以通过专注于在具有稳定API的平台上构建工具来节省开发时间和资金,从而确保他们的技术选择能够获得长期支持。

Eclipse体系结构介绍(二)_第3张图片

                               图6.6:Eclipse 3.0体系结构

查看图6.6中的3.0体系结构,您将注意到Eclipse Runtime仍然存在,以提供应用程序模型和扩展注册表。管理组件之间的依赖关系,插件模型现在由OSGi管理。除了继续能够为自己的IDE扩展Eclipse之外,消费者还可以构建基于RCP应用程序框架的更通用的应用程序。

 原文链接

你可能感兴趣的:(软件设计,Java,软件设计)