背景:
一个大的产品是由很多的插件构成。插件间的相互协作是必不可少的。
相互协作的典型方式是依赖,A依赖B,A就可以使用B中开放的包中的类了。(这种方式的优缺暂不讨论)
通过扩展扩展点的方式是另一种相互协作形式。
概念:
扩展点:一个可以支持特定功能的结构定义。 类比为方法的定义 这里主要是方法的入参格式定义 形参
扩展:自己或其他插件根据扩展点的定义格式 配置自己的参数 类比:方法的调用 设置实参
实现:在定义扩展点的插件里,会对应一段执行特定功能的逻辑,他通过全局变量和全局方法 虽然很绕 但一定得读懂
Platform.getExtensionRegistry().getConfigurationElementsFor(Activator.EXTENSION_ID);
检测并依次读取扩展点的所有扩展配置的参数 然后实现基于参数的特定功能。 类比:方法的实现 方法的内部逻辑
说明:
- 扩展点的本质是特定格式定义。作用在于:当其他插件想要进行扩展时,知道这个扩展点的功能和需要提供的参数类型。
- 实现是我自己弄出来的概念 但会帮助你理解。 这是段读取扩展的数据 执行特定功能的逻辑。 由于是通过平台基本的全局变量,所以它的定义位置非常灵活。分散到其他类甚至插件都是可以做到的, 当然不建议这么做。 简单的表达是: 定义和实现完全解耦。
理解以上两点后,下面的就容易理解了。
- 扩展点定义并不是必须的。即使扩展点的定义被删除了,但只要实现不改变(具体来说是需要更多的参数配置),扩展依然可以正常执行。下面是我的一个扩展定义
<extension point="wei.learn.rcp.extension.extender"> <extender className="wei.learn.rcp.extension.quote.actions.SecondAction" clienId="wei.learn.rcp.extension.quote.extender.clientld" id="wei.learn.rcp.extension.quote.extender" name="Action 2 菜单" type="action"> </extender> </extension>
我的实现:private void loadExtensions() { IConfigurationElement[] elements = Platform.getExtensionRegistry() .getConfigurationElementsFor("wei.learn.rcp.extension.extender"); if (elements == null || elements.length == 0) return; for (int i = 0; i < elements.length; i++) { IConfigurationElement element = elements[i]; ExtensionInfoBean bean = new ExtensionInfoBean(); bean.setId(element.getAttribute(ExtensionConstants.ATTR_ID)); bean.setName(element.getAttribute(ExtensionConstants.ATTR_NAME)); bean.setType(element.getAttribute(ExtensionConstants.ATTR_TYPE)); bean.setClientId(element .getAttribute(ExtensionConstants.ATTR_CLIENTID)); String index = element.getAttribute(ExtensionConstants.ATTR_INDEX); if (index == null || index.trim().isEmpty()) { bean.setIndex(100); } else { bean.setIndex(Integer.parseInt(index)); } bean.setDesc(element.getAttribute(ExtensionConstants.ATTR_DESC)); if (ExtensionConstants.TYPE_ACTION.equalsIgnoreCase(bean.getType())) { try { String classPath = element .getAttribute(ExtensionConstants.ATTR_CLASS); Object object = null; if (!classPath.isEmpty()) { object = element .createExecutableExtension(ExtensionConstants.ATTR_CLASS); } else { object = element .createExecutableExtension(ExtensionConstants.ATTR_CLIENTID); } if (object instanceof IAction) { bean.setAction((IAction) object); } } catch (Exception e) { e.printStackTrace(); } } appendGroup(bean); } }
并没有任何检测扩展是否符合扩展点定义的逻辑,只要扩展符合格式,实现找的扩展并能执行(如果少一些参数,就会报空指针异常)
扩展的定义中的point的值 是唯一纽带
当然没有扩展点的定义,你就不能够通过在插件编辑器的Extension-point下进行编辑定义扩展了,只能通过直接修改xml来实现。
总结:
扩展扩展点机制并没有什么玄妙的,平台在加载信息是把扩展信息注册,在另一地方会被读取执行。扩展点的名称是Key 扩展点的定义 规范了两边的格式,防止不匹配