利用OSGi解决Eclipse插件难题2011-10-21 IBM Bob Balfe使用 Open Services Gateway Initiative API 消除 Eclipse 插件依赖性本文介绍了一个采用 XML 的插件示例,以便为定义好的扩展点注册扩展。通过使插件能够感知 Extention Registry 并提供 OSGi 服务,我们可以完成这一完整的组件退耦操作。插件、扩展点、OSGi如您所知,Eclipse 的组件架构是基于插件 的 -- 这意味着将一组代码组件化为单一的组件,然后利 用 Eclipse 框架注册为其组件之一,其他组件可以绑定该组件或调用该组件。扩展点 是插件允许其他插 件向公开扩展点的插件提供附加功能的方法。现在利用所有这些插件并将其包装到受控的运行时,插件可 在其中动态进出,并且您可以获得 OSGi(基本上来说)。示例插件让我们从公开扩展点的基本插件开始,这样可以为同义词服务注册新的字符串映射。此项服务允许其 他服务注册一个词并将其映射到另一个词(同义词)。基本扩展包含非常简单的元素:一个词,当然还有 一个新的同义词。此插件扩展点的基本结构如表 1 所示。表 1. 示例插件的元素
| 插件名称 | com.company.SynonymRegistry |
| 扩展点 | 同义词 |
| 元素 | 词 -- 您想要为其添加同义词的词同义词 -- 您想要注册的同义词 |
我们还要将插件注册为 OSGi 服务。这意味着它只在显式执行此操作时被加载,并将可供其他客户声 明性地使用。为了使用该服务,其他客户只需了解 Interface 和 OSGi 类名称。在我们的示例中,我们 不会真正调用该服务,因为扩展点是假设的。我们将使用 OSGi API 以告知我们此项服务出入的时间,所 以我们可以正确地注册扩展点。现在这只是一个示例,并且使用针对此概念的扩展点可能不是最好的方法。我们用此基本示例要达到 的目的是如何动态注册新的扩展,同时说明使用 OSGi API 的插件生命周期事件。Mediator 插件下一个插件是第三方插件,该插件了解已知的服务和扩展点,但不想绑定到此插件,因为后面它将依 靠该插件进行运行时解析。这意味着该插件可以驻留在所引用的插件 (com.company.SynonymRegistry) 可能不存在的机器上。因为我们现在生活在 OSGi 和动态运行时世界,所以我们想确保插件在不引起运行 时故障或错误的情况下运行。我们的 mediator 插件将接受同义词的 XML 文件,并且通过使用提供的扩 展点用 SynonymRegistry 插件注册每个同义词。清单 1. 用于概念验证的示例 XML 文件
Synonyms.xml<?xml version="1.0" encoding="UTF-8"?><synonyms> <entry word="mediator" synonym="broker"/> <entry word="mediator" synonym="go-between"/> <entry word="mediator" synonym="interceder"/> <entry word="mediator" synonym="intermediary"/><synonyms>
Mediator 插件在其 start() 方法中做的第一件事是用 OSGi 服务注册为一个服务初始化侦听器。我 们要在传入 start() 方法的 BundleContext 对象上调用 OSGi 服务方法 addServiceListener()。以下 代码展示了一个通过传入代码和我们感兴趣的服务 ID 调用此 API 的示例。
context.addServiceListener( this, "com.company.SynonymRegistry" );
通过提供过滤器,可以告知 OSGi 服务注册中心只需通知您指定服务中的状态更改。在本例中,过滤 器只是 SynonymRegistry 类的类名称。您可能会寻根究底。答案就在启动序列中。在 OSGi 领域,我们不是总知道另一服务可用的时间,因 此我们需要对此进行说明。通过注册为服务侦听器,我们可得知服务开始和停止的时间。如果服务不可用 ,则允许我们缓存同义词。当服务确实可用时,我们会得到通知并注册扩展。