<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Live a simple life

    沉默(zhu_xing@live.cn)
    隨筆 - 48, 文章 - 0, 評論 - 132, 引用 - 0
    數據加載中……

    【Eclipse插件開發】Eclipse插件Lazy Start實現原理分析

             

    Eclipse插件Lazy Start實現原理分析

                                                                                        朱興zhu_xing@live.cn

           每次提到有關Eclipse插件啟動的問題的時候,腦子中自然的反應就是:可以設定為預先啟動(org.eclipse.ui.startup),否則默認的情況下是懶啟動(Lazy Start),只有當插件中的功能被真正調用的時候,插件才會被啟動。可能是人也跟著變懶了,也一直沒有去留心Eclipse底層是怎么實現這種懶加載的,只是有個大致的猜測,估計又是用hook機制了。昨天閑著具體看了一下實現,果然是類似的實現。下面就大致和大家分享一下,說的不一定準確,僅供參考 _~。

           直接進入主題,我們的Eclipse實例啟動肯定要構造工作區,那么ResourcesPlugin肯定會被啟動,我們就在ResourcesPlugin.startup方法設置一個斷點,調試棧如下:
        
        

             

        假設我們對插件類型加載細節不知道,猜測大致過程如下:

            1、 DefaultClassLoader加載類型(org.eclipse.core.resources.IContainer

            2、EclipseLazyStarter.preFindLocalClass

            3、 啟動資源插件:ResourcesPlugin.startup

             

        補充說明:

            1、 org.eclipse.osgi.internal.baseadaptor.DefaultClassLoaderEclipse針對OSGI類加載實現的核心角色,也是eclipse插件默認的類加載器類型,當然,每個插件有自己獨立的類加載器實例來負責類型加載。

            2、 DefaultClassLoaderBundleLoaderClasspathManager三者協作,處理類型加載請求(為什么一個類加載過程要搞的這么復雜呢?Eclipse的考慮是什么呢? 大家思考吧~_~)

        
            【EclipseLazyStarter調用分析】
            我們先大致看一下EclipseLazyStarter.preFindLocalClass方法的代碼實現

    1 public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurator {
    2     public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
    3         //首先判斷,如果不需要啟動則返回
    4          
    5          //如果插件正在啟動,則設定5000ms超時等待;如果超時,直接報錯返回
    6 
    7          //啟動插件
    8     }
    9 }
           

        加載類型之前為什么要給回調一下EclipseLazyStarter. preFindLocalClass,又hook了?我們看了一下EclipseLazyStarter繼承了ClassLoadingStatsHook接口,ClassLoadingStatsHook接口的類型API文檔說明了它的作用:

    A ClassLoadingStatsHook hooks into the <code>ClasspathManager</code> class.


            追蹤前面的調用棧,ClassLoadingStatsHook是在ClasspathManager.findLocalClass中被調用的:
            
     1 public Class findLocalClass(String classname) throws ClassNotFoundException {
     2         Class result = null;
     3         ClassLoadingStatsHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingStatsHooks();
     4         try {
     5             for (int i = 0; i < hooks.length; i++)
     6                 hooks[i].preFindLocalClass(classname, this);
     7             result = findLocalClassImpl(classname, hooks);
     8             return result;
     9         } finally {
    10             for (int i = 0; i < hooks.length; i++)
    11                 hooks[i].postFindLocalClass(classname, result, this);
    12         }
    13     }

            再接著往下看之前,我們大致已經知道來的Eclipse的插件lazy start是怎么回事了:
            EclipseLazyStarter hook到了插件類加載器的類型加載過程中了,在類型被加載之前會回調EclipseLazyStarter. preFindLocalClass方法:如果類型所在插件還沒啟動,啟動它;如果正在啟動,則設置5000ms的超時,限時不能完成啟動,則報錯返回!

       (附加說明:頭一段時間在另外一篇隨筆中,寫了一些編寫插件啟動類應該注意的點,其中有一條就是避免在插件啟動方法中干耗時的事情。這里真正告訴我們了原因:如果超過5000ms不能完成啟動--注意這其中還不包含所依賴插件的啟動時間,那么肯定會出現類加載超時的錯誤了:
         While loading class "{1}", thread "{0}" timed out waiting ({4}ms) for thread "{2}" to finish starting bundle "{3}". To avoid deadlock, thread "{0}" is proceeding but "{1}" may not be fully initialized.
        )

        【EclipseLazyStarter是如何完成注冊過程的?】
        
        過程簡要解釋如下:
        1、啟動osgi framework,兩種啟動方式:如果想利用Eclipse的一些特性,則就以EclipseStarter為入口點啟動;否則,可以用命令行的方式,以Laucher.main為入口點啟動
        2、初始化FrameworkAdaptor(對應eclipse實現是BaseAdaptor)看一下接口說明:
            
    /**
     * FrameworkAdaptor interface to the osgi framework. This class is used to provide
     * platform specific support for the osgi framework.
     *
     * <p>The OSGi framework will call this class to perform platform specific functions.
     *
     * Classes that implement FrameworkAdaptor MUST provide a constructor that takes as a
     * parameter an array of Strings.  This array will contain arguments to be
     * handled by the FrameworkAdaptor.  The FrameworkAdaptor implementation may define the format
     * and content of its arguments.
     *
     * The constructor should parse the arguments passed to it and remember them.
     * The initialize method should perform the actual processing of the adaptor
     * arguments.
     * <p>
     * Clients may implement this interface.
     * </p>
     * 
    @since 3.1
     
    */
          顯而易見,FrameworkAdaptor其實是osgi framework的后門,提供平臺附加支持。
           
          看一下BaseAdaptor的構造函數:
          
     1 /**
     2      * Constructs a BaseAdaptor.
     3      * @param args arguments passed to the adaptor by the framework.
     4      */
     5     public BaseAdaptor(String[] args) {
     6         if (LocationManager.getConfigurationLocation() == null)
     7             LocationManager.initializeLocations();
     8         hookRegistry = new HookRegistry(this);
     9         FrameworkLogEntry[] errors = hookRegistry.initialize();
    10         if (errors.length > 0)
    11             for (int i = 0; i < errors.length; i++)
    12                 getFrameworkLog().log(errors[i]);
    13         // get the storage after the registry has been initialized
    14         storage = getStorage();
    15         // TODO consider passing args to BaseAdaptorHooks
    16     }
          我們看到,調用了HookRegistry.initialize進行初始化
            
        3、初始化HookRegistry,我們直接看一下HookRegistry.initialize方法實現
            
     1 /**
     2      * Initializes the hook configurators.  The following steps are used to initialize the hook configurators. <p>
     3      * 1. Get a list of hook configurators from all hook configurators properties files on the classpath, 
     4      *    add this list to the overall list of hook configurators, remove duplicates. <p>
     5      * 2. Get a list of hook configurators from the (&quot;osgi.hook.configurators.include&quot;) system property 
     6      *    and add this list to the overall list of hook configurators, remove duplicates. <p>
     7      * 3. Get a list of hook configurators from the (&quot;osgi.hook.configurators.exclude&quot;) system property
     8      *    and remove this list from the overall list of hook configurators. <p>
     9      * 4. Load each hook configurator class, create a new instance, then call the {@link HookConfigurator#addHooks(HookRegistry)} method <p>
    10      * 5. Set this HookRegistry object to read only to prevent any other hooks from being added. <p>
    11      * @return an array of error log entries that occurred while initializing the hooks
    12      */
    13     public FrameworkLogEntry[] initialize() {
    14         ArrayList configurators = new ArrayList(5);
    15         ArrayList errors = new ArrayList(0); // optimistic that no errors will occur
    16         mergeFileHookConfigurators(configurators, errors);
    17         mergePropertyHookConfigurators(configurators);
    18         loadConfigurators(configurators, errors);
    19         // set to read-only
    20         readonly = true;
    21         return (FrameworkLogEntry[]) errors.toArray(new FrameworkLogEntry[errors.size()]);
    22     }

          其中的mergeFileHookConfigurators方法調用,讀取了一個名為hookconfigurators.properties的屬性配置文件,在org.eclipse.osgi插件中。看一下里面的內容:
         
     1 ###############################################################################
     2 # Copyright (c) 20052006 IBM Corporation and others.
     3 # All rights reserved. This program and the accompanying materials
     4 # are made available under the terms of the Eclipse Public License v1.0
     5 # which accompanies this distribution, and is available at
     6 # http://www.eclipse.org/legal/epl-v10.html
     7 #
     8 # Contributors:
     9 #     IBM Corporation - initial API and implementation
    10 ###############################################################################
    11 hook.configurators= \
    12  org.eclipse.osgi.internal.baseadaptor.BaseHookConfigurator,\
    13  org.eclipse.osgi.internal.baseadaptor.DevClassLoadingHook,\
    14  org.eclipse.core.runtime.internal.adaptor.EclipseStorageHook,\
    15  org.eclipse.core.runtime.internal.adaptor.EclipseLogHook,\
    16  org.eclipse.core.runtime.internal.adaptor.EclipseErrorHandler,\
    17  org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorHook,\
    18  org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook,\
    19  org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter,\
    20  org.eclipse.core.runtime.internal.stats.StatsManager,\
    21  org.eclipse.osgi.internal.verifier.SignedBundleHook
    22 


        ^_^,我們的EclipseLazyStarter赫然在列!!!

         
        回過頭來看一下EclipseLazyStarter(繼承ClassLoadingStatsHook)的使用方式:
        BaseAdaptor.getHookRegistry().getClassLoadingStatsHooks()

        前面已經看了ClasspathManager中findLocalClass方法的代碼,就是這么調用ClassLoadingStatsHook policy的(我們的EclipseLazyStarter...)

       【總結】
        hook了,osgi framework留了個后門,Eclipse好好的利用了這個后門~_~

       【附加說明】
        1、EclipseLazyStarter只是ClassLoadingStatsHook policy的實現,其實HookRegsitry中還有其他的hook policy,例如:
        org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook
        org.eclipse.osgi.baseadaptor.hooks.BundleFileWrapperFactoryHook
        org.eclipse.osgi.baseadaptor.hooks.BundleFileFactoryHook
        org.eclipse.osgi.baseadaptor.hooks.StorageHook
        org.eclipse.osgi.baseadaptor.hooks.AdaptorHook

        2、大家可以順帶詳細的看一下HookRegistry、HookConfigurator、BaseAdaptor等

        3、hook這種手法在Eclipse的資源管理中也有比較成功的應用,可以看一下
        org.eclipse.core.resources.team.IMoveDeleteHook
        例如cvs、ClearCase等團隊開發管理工具中,都實現了這種hook,通過擴展點org.eclipse.core.resources.moveDeleteHook動態掛入。大家有興趣可以深入看看,看過之后應該就明白了為什么cvs、ClearCase等一些團隊開發管理工具功能有一些不同了~_~
        
        4、對osgi感興趣的同學,可以看一下org.eclipse.osgi插件中的代碼,質量很高~_~
        亂轟轟的,湊合著看吧



    本博客中的所有文章、隨筆除了標題中含有引用或者轉載字樣的,其他均為原創。轉載請注明出處,謝謝!

    posted on 2008-08-19 18:05 zhuxing 閱讀(2657) 評論(2)  編輯  收藏 所屬分類: Eclipse Plug-in & OSGI

    評論

    # re: 【Eclipse插件開發】Eclipse插件Lazy Start實現原理分析  回復  更多評論   

    老弟,寫的通俗易懂一點好不好,看得比較暈:)

    鼓勵一下,很有鉆研精神!
    2008-08-20 21:23 | Always BaNg.

    # re: 【Eclipse插件開發】Eclipse插件Lazy Start實現原理分析  回復  更多評論   

    比較高深,迷茫中。。。。。。
    2008-12-06 09:58 | 楓葉KR
    主站蜘蛛池模板: 亚洲一区二区三区免费| 久久久久亚洲AV无码专区首JN | 瑟瑟网站免费网站入口| 日韩免费高清视频网站| 丰满亚洲大尺度无码无码专线| 永久免费不卡在线观看黄网站| 亚洲人精品午夜射精日韩| 两性色午夜免费视频| 久久精品国产亚洲av麻| 国产产在线精品亚洲AAVV| 99热免费在线观看| 国产亚洲成人久久| 免费人成网站在线观看不卡 | 亚洲精品国产精品乱码不卡√| 视频免费在线观看| 俄罗斯极品美女毛片免费播放| 免费看一级毛片在线观看精品视频| 日本zzzzwww大片免费| 久久综合久久综合亚洲| 亚洲一区二区三区免费在线观看| 亚洲国产美女在线观看| 免费网站看v片在线香蕉| 一级毛片免费播放视频| 国产一级淫片免费播放| 亚洲AV女人18毛片水真多| 最近最好的中文字幕2019免费| 亚洲精品中文字幕乱码| 欧洲精品成人免费视频在线观看 | 国产成人精品免费视频大| 亚洲日韩精品国产3区| 久久精品国产精品亚洲人人 | 麻豆国产VA免费精品高清在线| 日本黄页网址在线看免费不卡 | 亚洲成色WWW久久网站| 你懂的免费在线观看| 亚洲精品动漫在线| 免费一级黄色毛片| 99在线热视频只有精品免费| 国产AV无码专区亚洲AV麻豆丫 | 1000部拍拍拍18勿入免费视频下载 | 国产特黄特色的大片观看免费视频|