從classloader說起 頂 原

說起classloader可能最先想到的就是雙親委託。這次就換個角度來談這個。

從classloader到單例

單例是一種設計模式。表明上看好像和classloader沒有什麼關係。所以我們從單例的代碼入手開始考慮。

public class Singleton {

    private final static Singleton INSTANCE = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }
}

上面就單例的一種寫法,構造方法設置爲private,使用靜態方法來獲取對象。現在開始和classloader做聯繫。先想一個問題,是否能造出2個Singleton 對象。大家都這麼寫單例,貌似是不可以的。我現在自己寫兩個classloader,並且都有Singleton 的路徑,兩個loader都去加載初始化Singleton 。此時,內存裏就出現了兩個Singleton 對象。由於是兩個不同的loader加載的,兩個對象不能互相引用。那是否找個方式可以互相引用呢?下來騷操作出來了。給類加一個接口。

public class Singleton implements  SingletonInterface {

    private final static Singleton INSTANCE = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }
}

大家都知道雙親委託,現在有兩個自定義的loader有Singleton 的路徑,他們有共同的父loader,父loader可以加載到SingletonInterface 。次數兩個的Singleton 都可以賦值給SingletonInterface 了。現在就可以使用到了兩個單例類。他們都是Singleton ,但又不都是同一個Singleton。你也可以說在jvm裏, Singleton 不是單例了,你可以拿到多個Singleton 實例,而且還都可以做操作。

從classloader到類隔離

類隔離的用法算是classloder的最常見的用法了。尤其是在web容器中。webappclassloader是打破雙親委託的。都是先找自己loader的路徑,再找父。達到的效果就是webapp下有多個項目,每個裏面有相同的數據庫驅動,但是版本不一樣,他們都各自連接對應的數據庫。這種情況並不會出現類加載混亂,都保證了每個項目下的lib目錄優先,達到了類隔離的效果。

從classloader到熱部署

如果是項目級別的熱部署,那麼web容器也做到了,例如使用weblogic去上傳war應用,weblogic不需要停止,就可以把項目加載起來,就是靠新建一個classloader的獲取新的資源,然後加載。這裏再介紹一種一個項目內的熱部署。 目的:接口和實現分離,達到可以熱替換實現的地步,有點類似於我們電腦的鼠標,鍵盤——熱插拔。 如何設計呢。這裏必須參考一下spring的aop了。spring aop是生成了代理類的,爲什麼你運行的時候沒有察覺呢。得益於他的ioc。spring管理了你的對象,所以在你操作的時候,給你的對象其實是代理後的類對象。那麼想法也比較明朗了。我們需要一個ioc的功能,構建一個map。客戶端調用的時候,根據接口來調用,每次調用都需要從map中獲取。當想更改一些接口的實現的時候。可以通過某種介質來觸發,例如配置文件,利用目錄監控或者輪詢來獲取最新的配置,配置項就是接口和實現類的對於關係,這裏是不是有點眼熟,確實是spi的玩法。只不過我們可以直接打包新的類按照配置就可以做到不重啓,更改類的實現。代碼實現如下,有興趣的可以看看 https://github.com/xpbob/HotSwap

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