`
ihuashao
  • 浏览: 4724248 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

降低Eclipse RCP 项目 插件依赖度

阅读更多

Talend产品中,模块之间的依赖都是给予代码直接访问,每个插件项目没有自身的使用规则。造成插件间的混乱无序依赖。参见大型RCP项目,降低插件依赖度

例如:
上图中, org.talend.designer.core插件项目要依赖于如此多的其它项目。
从整个系统的体系结构看,org.talend.designer.core对于红线连接的插件的依赖是不符合逻辑的。
另外,其他插件之间也存在着相互依赖的情况,例如Runprocess就要依赖于Repository。
随着以后插件项目的增多,这么复杂的依赖型将导致软件的维护越来越困难。
解决的方案是提供一个服务的注册,提供机制,所有的服务在一个地方统一注册,其他插件到这里取用。
以Repository模块为例:可以体现为如下设计方案。
Repository作为服务的提供者,其他使用该功能的插件作为消费者。
实际实现
1 在基础项目org.talend.core中提供统一的服务注册接口程序如下:
packageorg.talend.core;

importjava.util.HashMap;
importjava.util.Map;

importorg.eclipse.core.runtime.CoreException;
importorg.eclipse.core.runtime.IConfigurationElement;
importorg.eclipse.core.runtime.IExtensionRegistry;
importorg.eclipse.core.runtime.Platform;
importorg.talend.commons.exception.ExceptionHandler;

/***//**
*DOCqianclassglobalcomment.Aglobalserviceregisterprovidestheserviceregistrationandacquirement.<br/>
*
*$Id:talend-code-templates.xml12006-09-2917:06:40+0000(星期五,29九月2006)nrousseau$
*
*/

publicclassGlobalServiceRegister...{

//Thesharedinstance
privatestaticGlobalServiceRegisterinstance=newGlobalServiceRegister();

privatestaticIConfigurationElement[]configurationElements;

publicstaticGlobalServiceRegistergetDefault()...{
returninstance;
}


privateMap<Class,IService>services=newHashMap<Class,IService>();

static...{
IExtensionRegistryregistry
=Platform.getExtensionRegistry();
configurationElements
=registry.getConfigurationElementsFor("org.talend.core.service");
}


/***//**
*DOCqianCommentmethod"getService".GetsthespecificIService.
*
*
@paramklasstheServicetypeyouwanttoget
*
@returnIServiceIService
*/

publicIServicegetService(Classklass)...{
IServiceservice
=services.get(klass);
if(service==null)...{
service
=findService(klass);
if(service==null)...{
thrownewRuntimeException("Theservice"+klass.getName()+"hasnotbeenregistered.");
}

services.put(klass,service);
}

returnservice;
}


/***//**
*DOCqianCommentmethod"findService".Findsthespecificservicefromthelist.
*
*
@paramklasstheinterfacetypewanttofind.
*
@returnIService
*/

privateIServicefindService(Classklass)...{
Stringkey
=klass.getName();
for(inti=0;i<configurationElements.length;i++)...{
IConfigurationElementelement
=configurationElements[i];
Stringid
=element.getAttribute("serviceId");

if(!key.endsWith(id))...{
continue;
}

try...{
Objectservice
=element.createExecutableExtension("class");
if(klass.isInstance(service))...{
return(IService)service;
}

}
catch(CoreExceptione)...{
ExceptionHandler.process(e);
}

}

returnnull;
}

}
2 服务接口为:
publicinterfaceIService...{

}
3 插件扩展点定义为;
org.talend.core/plugin.xml
<extension-pointid="service"name="ServiceRegistration"schema="schema/service.exsd"/>
4对于希望提供服务插件需要声明自己的服务类型。
例如org.talend.repository插件希望提供服务。
定义IRepositoryService.java 此类放入org.talend.core中。
在org.talend.repository实现IrepositoryService
publicinterfaceIRepositoryServiceextendsIService...{

publicIComponentsFactorygetComponentsFactory();

publicIPathgetPathFileName(StringfolderName,StringfileName);

publicIProxyRepositoryFactorygetProxyRepositoryFactory();

publicIPathgetRepositoryPath(RepositoryNodenode);
}
publicclassRepositoryServiceimplementsIRepositoryService...{

publicIComponentsFactorygetComponentsFactory()...{
returnComponentsFactoryProvider.getInstance();
}


publicIPathgetPathFileName(StringfolderName,StringfileName)...{
returnRepositoryPathProvider.getPathFileName(folderName,fileName);
}


publicIProxyRepositoryFactorygetProxyRepositoryFactory()...{
returnProxyRepositoryFactory.getInstance();
}


publicIPathgetRepositoryPath(RepositoryNodenode)...{
returnRepositoryNodeUtilities.getPath(node);
}

}
5 org.talend.repository使用扩展点,使自己注册到org.talend.core中.
org.talend.repository/plugin.xml
<extension
point="org.talend.core.service">
<Service
serviceId="IRepositoryService"
class
="org.talend.repository.RepositoryService"/>
</extension>
6 消费者使用org.talend.repository提供的服务时,只需要调用
/***//**
*DOCgetaimplementofIRepositoryService.
*
*
@returnaimplementofIRepositoryService
*/

publicIRepositoryServicegetRepositoryService()...{
IServiceservice
=GlobalServiceRegister.getDefault().getService(IRepositoryService.class);
return(IRepositoryService)service;
}
经过这样的改造,所有的插件都只要依赖org.talend.core即可,解决了插件间依赖结构混乱的问题。而且系统具有很好的开放性,很容易的加入其他服务的注册,有利于今后的扩展。
P.S. 一开始想利用Eclipse 的getAdaptable(Class) 机制来实现此功能,虽然也能实现,但是使用者还要自己写Facotry类,增加了扩展的难度,而且getAdaptable(Class)机制也不是用来解决这种问题的。而且自己控制服务的加载可以避免很多额外的麻烦。
分享到:
评论

相关推荐

    Eclipse RCP 插件开发指南

    本指南旨在帮助开发者从零开始掌握Eclipse RCP插件开发的基础知识及实战技巧。 ##### Introduction Eclipse RCP 是一个灵活的平台,它提供了构建桌面应用程序所需的所有组件和服务。通过使用Eclipse RCP,开发者...

    Eclipse RCP培训.zip

    11. **插件开发**:开发Eclipse RCP应用涉及创建插件项目、定义插件依赖、编写插件XML配置文件,以及实现具体业务逻辑。 12. **调试与测试**:Eclipse RCP提供强大的调试工具,如插件调试器,可以帮助开发者定位和...

    通过例子学习EclipseRCP开发

    当启动一个RCP应用时,Eclipse首先加载核心插件,然后根据插件之间的依赖关系加载其他插件。工作台(Workbench)会初始化并加载所有已注册的透视图、编辑器、视图等。一旦初始化完成,用户就可以与应用程序交互了。 ...

    Eclipse RCP+Spring建胖客户端Web程序

    - **强大的社区支持**:由于Eclipse项目本身的活跃度很高,因此围绕Eclipse RCP也形成了一个庞大且活跃的开发者社区,可以提供丰富的资源和支持。 #### 3. 实现步骤 ##### 3.1 创建新的Eclipse插件工程 - **准备...

    eclipse rcp demo

    7. **插件依赖和声明**:理解如何在MANIFEST.MF文件中声明插件依赖以及使用Plugin.xml配置文件。 通过"rcp_demo"的学习,你将能够掌握Eclipse RCP的基本用法,进一步了解如何设计和实现一个完整的桌面应用程序。...

    Eclipse RCP 属性编辑器实例

    6. **测试与调试**:使用Eclipse RCP自带的插件开发环境(PDE)进行测试和调试。你可以运行插件并查看属性编辑器是否按预期工作,同时检查日志和错误报告以解决可能出现的问题。 在"plugins"目录中,你可能会找到...

    eclipse插件开发 rcp入门开发详细讲解一

    ### Eclipse RCP插件开发详解 #### 一、Eclipse RCP概述 Eclipse RCP (Rich Client Platform) 是一种基于Java技术构建的框架,用于开发功能丰富的桌面应用程序。它利用了Eclipse平台的核心组件,如工作台...

    使用Eclipse RCP进行桌面程序开发

    - 添加依赖插件,确保包含了当前项目自身。 - 设置构建路径。 - 导出程序至指定目录。 5. **运行导出的程序**: - 导出的程序中包含一个类似Eclipse的程序图标,双击即可运行。 - 如果希望程序有自己的图标,...

    Eclipse_RCP_自学教程.doc

    创建 RCP 程序需要在 Eclipse IDE 中新建一个 RCP 项目,然后配置所需的插件和主类。启动 RCP 程序通常通过运行配置中的“Eclipse Application”来完成。 5. 应用程序 VS 产品 - 应用程序(Application):是 RCP...

    Eclipse RCP 自学教程

    在Eclipse插件开发中,正确管理插件ID至关重要,因为它影响着插件之间的依赖关系和通信。 ### 4. Actions的用法(菜单和工具栏) #### 4.1. 概述 Actions是用户界面交互的核心,它们与菜单项、工具栏按钮等UI元素...

    EclipseSWT_JFace_RCP插件开发

    5. **源代码分析**:在"**EclipseSWT_JFace_RCP插件开发**"的源代码中,我们可以期待找到如何使用SWT和JFace创建用户界面,以及如何利用RCP框架构建可扩展应用的示例。开发者可能通过这些代码学习到如何组织插件结构...

    Eclipse RCP教程

    - **插件**:Eclipse RCP 应用程序的核心构建单元,每个插件负责特定的功能或服务。 - **OSGi**:一种模块化系统和动态模块加载器,使插件能够动态加载、卸载、启动和停止。 - **扩展点**:定义在插件中的接口,允许...

    Eclipse RCP自学教程

    开发Eclipse RCP应用主要涉及到创建插件项目,定义插件元数据,编写插件代码,最后打包成插件或产品。Eclipse IDE提供了丰富的工具和模板来简化这个过程。 10. **调试和测试** Eclipse RCP提供了强大的调试环境,...

    开发你的第一个EclipseRCP应用程序汇编.pdf

    1. **创建项目**:在Eclipse中,开发者可以通过选择特定的RCP模板来初始化一个新的项目。 2. **定义工作台**:RCP应用程序的核心是工作台,开发者需要配置工作台的行为,如窗口布局和视图管理。 3. **添加视图和操作...

    Eclipse RCP开发SDK_3.6.2.rar

    1. **创建项目**:使用Eclipse IDE创建一个新的RCP项目,选择合适的模板和依赖。 2. **定义扩展点**:根据需求定义应用的扩展点,声明新的视图、编辑器或者其他功能。 3. **实现部件**:编写代码实现部件,包括视图...

    Eclipse 4.3 RCP 最新英文教程

    Eclipse 4.3 RCP 旨在为开发者提供了一个新的编程模型,该模型基于注解(annotations)和依赖注入(dependency injection),从而简化了Eclipse应用程序的开发。Eclipse 4 应用程序模型的引入,使得应用程序的开发与...

    通过例子学习Eclipse RCP开发

    - **插件**:插件是 Eclipse RCP 应用程序的基本单元。每个插件都是一个独立的单元,可以包含代码、资源和其他数据。插件之间可以通过扩展点进行交互。 - **扩展点**:扩展点定义了插件可以提供的服务或功能,其他...

Global site tag (gtag.js) - Google Analytics