`
dadi520
  • 浏览: 144831 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

(转)降低Eclipse RCP 项目 插件依赖度(OSGI 服务的理解)

阅读更多

 

下面这篇文章思路颇有点 osgi service 意思, 有思想的可以看看

 

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

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

import java.util.HashMap;
import java.util.Map;

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

/**
 * DOC qian class global comment. A global service register provides the service registration and acquirement. <br/>
 * 
 * $Id: talend-code-templates.xml 1 2006-09-29 17:06:40 +0000 (星期五, 29 九月 2006) nrousseau $
 * 
 
*/

public class GlobalServiceRegister {

    
// The shared instance
    private static GlobalServiceRegister instance = new GlobalServiceRegister();

    
private static IConfigurationElement[] configurationElements;

    
public static GlobalServiceRegister getDefault() {
        
return instance;
    }


    
private Map<Class, IService> services = new HashMap<Class, IService>();

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


    
/**
     * DOC qian Comment method "getService".Gets the specific IService.
     * 
     * 
@param klass the Service type you want to get
     * 
@return IService IService
     
*/

    
public IService getService(Class klass) {
        IService service 
= services.get(klass);
        
if (service == null{
            service 
= findService(klass);
            
if (service == null{
                
throw new RuntimeException("The service " + klass.getName() + " has not been registered.");
            }

            services.put(klass, service);
        }

        
return service;
    }


    
/**
     * DOC qian Comment method "findService".Finds the specific service from the list.
     * 
     * 
@param klass the interface type want to find.
     * 
@return IService
     
*/

    
private IService findService(Class klass) {
        String key 
= klass.getName();
        
for (int i = 0; i < configurationElements.length; i++{
            IConfigurationElement element 
= configurationElements[i];
            String id 
= element.getAttribute("serviceId");
            
            
if (!key.endsWith(id)) {
                
continue;
            }

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

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

        }

        
return null;
    }

}
 
 
2 服务接口为:
 
public interface IService {

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

    
public IComponentsFactory getComponentsFactory();

    
public IPath getPathFileName(String folderName, String fileName);
    
    
public IProxyRepositoryFactory getProxyRepositoryFactory();
    
    
public IPath getRepositoryPath(RepositoryNode node);
}
 
public class RepositoryService implements IRepositoryService {

    
public IComponentsFactory getComponentsFactory() {
        
return ComponentsFactoryProvider.getInstance();
    }


    
public IPath getPathFileName(String folderName, String fileName) {
        
return RepositoryPathProvider.getPathFileName(folderName, fileName);
    }


    
public IProxyRepositoryFactory getProxyRepositoryFactory() {
        
return ProxyRepositoryFactory.getInstance();
    }

    
    
public IPath getRepositoryPath(RepositoryNode node){
        
return RepositoryNodeUtilities.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提供的服务时,只需要调用
 
/**
     * DOC get a implement of IRepositoryService.
     * 
     * 
@return a implement of IRepositoryService
     
*/

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

 

分享到:
评论

相关推荐

    在Eclipse RCP中应用Spring OSGI 管理bean(一)

    标题中的“在Eclipse RCP中应用Spring OSGI 管理bean(一)”表明这是一篇关于如何在Eclipse Rich Client Platform (RCP)应用程序中集成Spring框架,并利用OSGi服务来管理Bean的教程。Eclipse RCP是一个用于构建桌面...

    Eclipse RCP 插件开发指南

    通过本指南的学习,您应该已经对 Eclipse RCP 插件开发有了全面的理解。从插件体系结构到具体的用户界面组件设计,每一个知识点都旨在帮助开发者构建出高质量、可扩展的应用程序。未来,在掌握了基础知识后,您可以...

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

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

    Eclipse RCP自学教程

    Eclipse RCP的核心是其插件系统,它基于OSGi模块化系统,使得应用可以由多个互相独立的组件构成。每个组件(或称为插件)都有自己的生命周期和上下文,可以单独开发、更新和调试,降低了整体复杂性。 2. **工作台...

    Eclipse RCP教程

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

    eclipse rcp 指南

    - **运行时环境**:Equinox 是 Eclipse RCP 的运行时环境,它是一个基于 OSGi 的实现,负责管理插件的加载、激活和生命周期。 - **OSGi**:OSGi 规定了插件(在 OSGi 中称为 bundle)的标准,包括 API 定义、依赖...

    Eclipse+RCP框架分析和应用研究.pdf

    Eclipse RCP框架的实现依赖于多项关键技术和架构,包括SWT/JFace、Eclipse插件结构和OSGi: 1. **SWT/JFace**:SWT(Standard Widget Toolkit)是一个高效的图形用户界面工具包,能够生成原生操作系统上的界面元素...

    eclipse rcp架构介绍PPT

    Eclipse RCP 利用 Eclipse 的核心组件和技术,如 OSGi 和 Equinox,来构建灵活且可扩展的应用程序。 - **平台无关性**:支持在不同的操作系统上运行,包括 Windows、Linux 和 macOS。 - **高度可定制**:用户可以...

    eclipse插件开发: rcp/swt相关资料

    Eclipse插件开发是Java开发领域中的一个重要组成部分,它允许开发者构建基于...掌握以上知识点,并通过实际项目练习,开发者可以熟练地进行Eclipse插件开发,利用RCP和SWT构建出高效、美观且功能强大的桌面应用程序。

    RCP,RCP开发

    **RCP(Rich Client Platform)与OSGI详解** **RCP概述** RCP,全称为Rich Client Platform,是由Eclipse基金会开发的一种软件框架,...在实际项目中,理解并熟练运用RCP和OSGI技术,能大大提高开发效率和软件质量。

    eclipse插件开发实战

    通过上述内容的深入分析,我们可以看出 Eclipse 插件开发不仅涉及内核结构的理解,还包括 SWK、OSGi 和 RCP 的掌握,以及实际的插件项目构建和发布流程。对于想要深入了解 Eclipse 插件开发的技术人员来说,这些知识...

    Eclipse-4-RCP教程1

    Eclipse 应用程序通常由多个插件组成,这些插件通过 OSGi 模块系统相互协作。每个插件可以提供特定的功能,而整个应用程序的架构则是这些插件的集合。 3. **Eclipse 平台的核心组件** 核心组件包括工作台...

    eclipse插件开发指南

    在项目中,你会看到几个关键的文件和目录,如`plugin.xml`,它是插件的配置文件,定义了插件的元数据、提供的服务和依赖关系。 在`plugin.xml`中,你可以声明插件的扩展点(Extension Points),这是Eclipse插件...

    eclipse 插件开发

    接下来,你需要理解插件项目结构。一个基本的插件项目通常包含以下元素: 1. `plugin.xml`:这是插件的核心配置文件,它定义了插件的元数据,包括ID、版本、依赖项以及扩展点和贡献。 2. `src`目录:包含插件的源...

    Eclipse插件开发资料

    本文将深入探讨Eclipse插件开发的相关知识点,帮助开发者更好地理解和实践。 一、Eclipse插件体系结构 Eclipse的核心设计理念是模块化,它通过插件系统构建了一个高度可扩展的平台。每个插件都是一个独立的功能单元...

    Eclipse插件开发教程

    开发Eclipse插件首先需要安装Eclipse IDE for RCP and RAP Developers,其中包含了插件开发所需的工具和运行时环境。此外,还需要下载并安装Eclipse Plug-in Development Environment (PDE)工具。 3. **创建第一个...

    RCP程序中集成其他插件的配置方法

    4. **插件注册**: 在新插件的清单文件中,定义服务(如`org.eclipse.ui.views`、`org.eclipse.ui.perspectiveExtensions`等),并使用`plugin.xml`进行可视化配置。这将确保新插件的视图、透视图或其他元素能在RCP...

    eclipse 插件开发入门

    总的来说,学习"eclipse 插件开发入门"不仅需要理解SWT/JFace的UI设计原理,还要掌握OSGi的模块化机制,熟悉RCP的架构,以及运用EMF和GEF进行模型驱动和图形化编辑。通过这些技术的学习,开发者可以高效地构建出强大...

    RCP+Plug-in开发自学教程_RCP+Plug-in开发自学教程_源码

    1. **OSGi服务**:Eclipse RCP基于OSGi框架,提供动态服务发现和依赖管理,有助于保持系统的灵活性和稳定性。 2. **国际化**:支持多语言,通过资源包(.properties文件)实现文本的本地化。 3. **自定义启动器**:...

Global site tag (gtag.js) - Google Analytics