OSGI in Action 讀書筆記 第三章

OSGI in Action 讀書筆記 第三章
第三章 學習生命週期
    本章將幫助您熟悉的生命週期層的功能,並解釋如何有效地使用它們。在下一節中,我們將仔細看看什麼生命週期管理,爲什麼你應該關心它的定義,其次是OSGi包的生命週期。在隨後的章節中,您將瞭解的API,用於管理bundle的生命週期。
3.1 lifecycle層介紹
    1、在應用程序外部定義了bundle的生命週期操作。
    2、在內部定義瞭如何使bundle訪問OSGI的執行上下文
3.1.1 什麼是生命週期管理
    通過JMX、及普通的桌面應用程序說明了生命週期一般要經歷的過程:安裝、執行、更新、卸載。
    通過Standard Java及Servlet說明java是如何管理其生命週期的。
3.1.2 爲什麼要使用生命週期管理
    1、提供了更細粒度的生命週期管理——bundle的生命週期管理;
    2、提供了一組標準的生命週期管理API;
    3、可以按需使用組件,爲應用程序提供更多的靈活性。
3.2 OSGI bundle的生命週期
    在module層,我們爲其提供了原數據,已支持其模塊性,而生命週期層則不需要依賴於任何的元數據或xml配置文件,他所依賴的是一組標準的api.
    由於沒有標準的方式爲用戶進行交互的生命週期API,你可以使用一個基於OSGI標準的框架框架。但是,這將使我們錯失一個很好的學習的機會。
小貼士:殼、殼、殼到處是殼  
    在OSGI標準的多個實現中(如:Apache Felix, Eclipse Equinox,Knopflerfish)都定義了自己的Shell,用以與運行的OSGI交互。OSGI並沒有定義標準的Shell,儘管osgi做了一些相關的工作,但是Shell不必綁定到特定的框架,shell也可以作爲bundle實現,就像你在這裏做的一樣。
3.2.1介紹生命週期的畫圖程序
    使用Paint程序展示OSGI的動態性。值得研究的還有telnet通訊。
    使用的示例shell和paint,採取自上而下的的方法來學習:
    在3.2.2節中,我們將解釋在應用程序的生命週期中框架承擔的角色。
    在3.2.3節中,我們來看看需要對manifest做如何調整已使bundle鉤如到OSGI框架中。
    在3.2.4節中,我們將研究OSGi生命週期的關鍵API接口:BundleActivator, BundleContext,Bundle。
    在3.2.5節中,在結束時,議論OSGi的生命週期狀態圖。
3.2.2 在生命週期管理中OSGI框架擔任的角色
    在標準的Java編程中,可以將JAR文件放置在類路徑中,已完成jar包的導入(安裝),但這不是安裝bundle的方法。bundle在使用之前必須安裝到正在運行的OSGi框架實例。從概念上講,你可以認爲安裝bundle就類似於將一個JAR文件放置到標準java的類路徑中。
    一個很大的區別的是,OSGi框架支持對bundle完整的生命週期管理,包括安裝、解析、啓動,停止,更新和卸載。到此,我們只談到了安裝bundle並解決他們的依賴關係。本章的其餘部分將全面解釋生命週期的活動,以及他們是如何相互關聯的。例如,我們已經提到過,框架不允許bundle使用,直到它的依賴滿足。
    另一個重大區別是,OSGi框架在運行時對bundle提供完整的生命週期管理支持。這類似於動態的修改類路徑!
    作爲生命週期管理的一部分,框架對安裝包(bundle)進行了緩存,並做了持久化。這意味着下一次啓動的框架,任何安裝包將自動重新加載到緩存中,原JAR文件不再需要了。或許這可以作爲一個框架的特點:受控的,動態的,持久化的類路徑。這聽起來很酷,對吧?如何讓我們繼續?你必須修改元數據,允許bundle鉤入到生命週期層的API。
3.2.3 manifest的bundle activator元素
    Bundle-Activator: org.foo.shell.Activator
小貼士 Bundle-Activator是不是必須的?
    BundleActivator並不是對於每個bundel必須的。只有那些需要與OSGI AIP交互的或者需要定製其初始與銷燬行爲的bundle才需要。沒有Activator的Bundle並非沒用。他可能提供一些公用的Class
3.2.4 生命週期管理API介紹
    BUNDLE ACTIVATOR
    public interface BundleActivator {
        public void start(BundleContext context) throws Exception;
        public void stop(BundleContext context) throws Exception;
    }
    Simple shell bundle activator
    package org.foo.shell;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    public class Activator implements BundleActivator {
        private volatile Binding m_binding;
        public void start(BundleContext context) {
            int port = getPort(context);
            int max = getMaxConnections(context);
            m_binding = getTelnetBinding(context, port, max);
            m_binding.start();
            System.out.println("Bundle " +
            context.getBundle().getSymbolicName() +
            " started with bundle id" +
            context.getBundle().getBundleId() +
            " listening on port " + port);
        }
        public void stop(BundleContext context) {
            m_binding.stop();
        }
        ...
    }
    ...
    public interface Binding {
    public void start();
    public void stop() throws InterruptedException;
    }
    當bundle被裝載且開始的時候,框架實例化一個Activator並且調用start()方法。當bundle結束的時候,調用已實例化的Activator的stop()方法。當stop()方法調用時。Activator的實例將被丟棄。如果對一個已經停止的bundle重新開始。則重新實例化一個新的Activator實例。
    OSGI規範並不要求你在start()方法中啓動一個新的進程。

小貼士 OSGI的線程安全問題

    OSGi是普通的Java線程抽象設計的。不像其他的大多數重量級的框架,它假定你自己對線程進行管理。這樣你獲得了更多的自由,但同時你必須確保你的
程序正確同步和線程安全。在這個簡單的例子中,沒有什麼是特別是必要的,但在一般情況下,你很可能在不同的線程中調用stop()和start()方法。
    OSGi的庫是線程安全的,並且通常是在回調的方式給你一定的保證。例如,在bundle activator中start()和stop()以保證按順序調用,不能同時使用。所以,在技術上,
這種特殊情況下的揮發可能不是必要的。

    
    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章