Eclipse插件體系結(jié)構(gòu)

          Posted on 2009-07-28 16:07 eric_xu 閱讀(1852) 評論(0)  編輯  收藏 所屬分類: Eclipse Plugin

          插件是為系統(tǒng)提供功能的代碼和/或數(shù)據(jù)的結(jié)構(gòu)化包。可以以代碼庫(帶有公共 [應用程序接口] API Java 類)、平臺擴展甚至文檔的形式來提供功能。插件可以定義擴展點、定義良好的位置,其他插件可以在這些位置添加功能。

          Eclipse使用OSGi作為插件系統(tǒng)的基礎(chǔ)。動態(tài)添加新插件和停止現(xiàn)有插件的能力。以動態(tài)方式管理組件生命周期的一個健壯的系統(tǒng)。

          OSGi是基于Java的框架,旨在用于需要長運行時間、動態(tài)更新和對運行環(huán)境破壞最小的系統(tǒng)。

          OSGi規(guī)范定義了綁定包生命周期的基礎(chǔ)架構(gòu)和綁定包的交互方式。這些規(guī)則通過使用特殊 Java類加載器來強制執(zhí)行。

          在一般Java應用程序中,CLASSPATH中的所有類都對所有其他類可見。相反,OSGi類加載器基于OSGi規(guī)范和每個綁定包的manifest.mf文件中指定的選項來限制類交互。

          3.1之前版本的Eclipse中,在每個插件的plugin.xml文件中定義插件依賴關(guān)系以及擴展和擴展點。在使用OSGi的新版本Eclipse中,依賴關(guān)系信息被分解到manifest.mf文件中,而 plugin.xml文件只包含擴展和擴展點的XML定義。

          插件級的依賴關(guān)系改為需要顯式導出和導入包的依賴關(guān)系。插件開發(fā)人員必須進行專門選擇來使插件中的功能可供外部使用。該限制允許內(nèi)部包保留在內(nèi)部,避免插件暴露不必要的類。

          Eclipse的擴展和擴展點 可插拔

          每一個希望被別的模塊擴展的模塊,都必須聲明一系列的擴展點,即插座;希望在這個模塊上擴展功能的模塊,需要按照擴展點的什么來編寫擴展,即插頭。擴展點提供服務,擴展是要服務。

          延遲裝載,只有在一個插件被其他模塊調(diào)用的時候,才裝載到內(nèi)存中。

          通過將擴展的聲明和實現(xiàn)分離,eclipse實現(xiàn)類延遲裝載。

          擴展點和擴展的聲明都是通過XML文件完成的,即清單文件MANIFEST.MF,描述了一個插件能夠做什么,而JAVA代碼則具體完成這些功能。系統(tǒng)啟動時,只需搜索清單文件,建立一張索引表,知道有哪些插件以及能夠提供什么服務。當eclipse第一次啟動時,eclipse運行時會遍歷plugins文件夾中的目錄,掃描每個插件的清單文件信息,并建立一個內(nèi)部模型來記錄它所找到的每個插件的信息。

          RCP包括基于OSGi的運行時框架Equniox,基于SWT/JFace的圖形模塊,eclipse平臺的UIRuntime模塊。基于Eclipse的應用程序所需的最小插件集稱為Eclipse Rich Client PlatformRCP


          Platform Runtime 平臺運行庫是內(nèi)核,它在啟動時檢查已安裝了哪些插件,并創(chuàng)建關(guān)于它們的注冊表信息。即在eclipse運行時發(fā)現(xiàn)和管理插件。為降低啟動時間和資源使用,它在實際需要任何插件時才加載該插件。除了內(nèi)核外,其他每樣東西都是作為插件來實現(xiàn)的。

          Workspace 工作區(qū)是負責管理用戶資源的插件。這包括用戶創(chuàng)建的項目、那些項目中的文件,以及文件變更和其他資源。工作區(qū)還負責通知其他插件關(guān)于資源變更的信息,比如文件創(chuàng)建、刪除或更改。

          Workbench 工作臺為Eclipse提供用戶界面。它是使用標準窗口工具包(SWT)和一個更高級的 APIJFace)來構(gòu)建的;SWT Java Swing/AWT GUI API 的非標準替代者,JFace 則建立在 SWT 基礎(chǔ)上,提供用戶界面組件。

          插件可以扮演雙重角色,其他插件服務的使用者和其他插件服務的提供者。

           

          manifest.mf

          Bundle-Activator

          該類用于啟動和停止綁定包。該類擴展 org.eclipse.core.runtime.Plugin,實現(xiàn)了 BundleActivator 接口。

          Bundle-Version

          該屬性指定綁定包的版本號。包導入和必需的綁定包規(guī)范可以包括綁定包版本號。

          Export-Package

          該屬性指定要公共暴露給其他插件的所有包。

          Import-Package

          該屬性指定要從必需插件中顯式導入的所有包。默認情況下,必須為要啟動的綁定包解析所有包。還可以將包導入指定為可選項,以支持包不存在的情況。顯式導入的類在 Require-Bundle 插件中的包之前解析。

          Require-Bundle

          該屬性指定要在給定綁定包中導入使用的綁定包及其已導出的包。指定的綁定包在顯式包導入之后解析。

           

           

          ----------------------            --------------------
          |plugin A            |            |plugin B          |
          |   ---------------  | contibute  |  --------------  |
          |   | ext point p | <--------------- | extension  |  |
          |   ---------------  |_           |  --------------  |
          |         ||         | |          |        ||        |
          |   ---------------  | |implement |  --------------  |
          |   | interface I | <--|------------ | class  C   |  |
          |   ---------------  | |          |  --------------  |
          ---------------------- |          ----------/ -------
                                 |  create, call       |
                                 ----------------------|

          你可以把extension point想為接口而我們擴展這些extension,其實就是實現(xiàn)了這個接口

          假設(shè)plugin A定義了一個extension point,  plugin B定義了一個extension,是基于plugin A的這個extension point,它的實現(xiàn)類是class C,eclipse啟動后會讀取每個plugin的配置plugin.xml,然后發(fā)現(xiàn)plugin B有一個基于ext point p的擴展,那它就會用interface I作為對象然后實例化一個class C, 就等于實現(xiàn)了這個extension

           

          eclipse的內(nèi)部實現(xiàn)
          IPluginRegistry registry = Platform.getPluginRegistry();
          IExtensionPoint extensionPoint = registry.getExtensionPoint(xpid); //
          通過擴展點ID獲得擴展點
          IExtension[] extensions = extensionPoint.getExtensions(); //
          獲得該擴展點的所有擴展
          // For each extension ...
          for (int i = 0; i < extensions.length; i++) {
              IExtension extension = extensions[i];
              IConfigurationElement[] elements = extension.getConfigurationElements(); //
          獲得擴展點配置元素
              configurationElement[j].createExecutableExtension(“Class”); //
          為每個回調(diào)對象創(chuàng)建實例

              ……
          }
          eclipse
          就是注冊每一個extensionextension point,然后用extension point來實例化它對應的那個extension

          發(fā)生事件并向其它對象請求處理的對象被稱為事件對象,而處理事件的對象被稱為回調(diào)對象。回調(diào)對象由擴展者插件定義,由宿主插件創(chuàng)建實例。

          Eclipsebundle使用各自的class loader,若需要引用其他bundle類來動態(tài)創(chuàng)建實例,則需要使用類所在的bundleclass loader

          posts - 37, comments - 5, trackbacks - 0, articles - 0

          Copyright © eric_xu

          主站蜘蛛池模板: 紫阳县| 大悟县| 桃源县| 通山县| 多伦县| 运城市| 咸阳市| 盘锦市| 天等县| 桦甸市| 伊川县| 莫力| 张家港市| 新宁县| 凌源市| 汾西县| 鹰潭市| 九江市| 巩义市| 常宁市| 光山县| 青田县| 宁安市| 宕昌县| 会泽县| 诸城市| 漳平市| 邯郸市| 屏山县| 五常市| 湛江市| 兴和县| 仁怀市| 新巴尔虎右旗| 中江县| 佛坪县| 炎陵县| 彭阳县| 屏东市| 滁州市| 宿迁市|