Doraemon —— 一個(gè)輕量級Java模塊化隔離框架

相關(guān)代碼,見我的開源項(xiàng)目:
https://github.com/qianxingchuan/doraemon

簡介

2017年,我在菜鳥物流云這個(gè)部門做了一個(gè)叫做Asgard的網(wǎng)關(guān),當(dāng)時(shí)為了快速實(shí)現(xiàn),只適配了阿里巴巴的技術(shù)棧體系,比如鑒權(quán)的部分,直接把菜鳥的賬號系統(tǒng)接入的代碼固化在網(wǎng)關(guān);再比如調(diào)用服務(wù)的部分,直接把泛化調(diào)用HSF的代碼固化在網(wǎng)關(guān)。這些固化代碼的方式,對于Asgard的可擴(kuò)展性和靈活性都造成了無比巨大的限制。

從菜鳥離職之后,在2019年5月,在vivo做關(guān)于云存儲相關(guān)的項(xiàng)目,vivo的基礎(chǔ)設(shè)施不是特別完美,所以存在很多重復(fù)勞動,比如幾乎每個(gè)web應(yīng)用都會寫一套一模一樣的app鑒權(quán)、web鑒權(quán),以及通用的cors的配置。這一點(diǎn)我非常不爽,所以決定在vivo重新把Asgard寫一遍,這次重寫,必定完善之前菜鳥物流云時(shí)期沒有時(shí)間做的一些事情,比如高度可自定義每個(gè)調(diào)用階段,再比如網(wǎng)關(guān)必須要支持響應(yīng)式、全異步,以及支持websocket等等。

既然要實(shí)現(xiàn)高度自定義,那么我們需要有一套高度可插拔的plugin處理框架,osgi太重了,我不想我們的應(yīng)用有太多這樣的依賴,以及發(fā)布規(guī)范; 螞蟻金服有一套開源的sofa-ark,也能滿足我的要求,但是對于我來說,還是不夠輕量級,我其實(shí)只要能在網(wǎng)關(guān)應(yīng)用內(nèi)部可以獨(dú)立每個(gè)plugin即可,如圖1:


圖1

本文重點(diǎn)介紹我基于Java類加載器實(shí)現(xiàn)的一個(gè)輕量級模塊隔離框架:Doraemon。
在同一個(gè)JVM里面,我們的應(yīng)用程序可以調(diào)用任意一個(gè)bundle的export出來的實(shí)例,bundle互相之間不可見。

Doraemon快速使用

實(shí)現(xiàn)基于鑒權(quán)接口的不同實(shí)現(xiàn)

樣例工程見doraemon-sample

主要工程:
sample-auth-facade : 鑒權(quán)的接口定義
sample-auth-bundle1 : 基于鑒權(quán)接口的實(shí)現(xiàn)1
sample-auth-bundle2 : 基于鑒權(quán)接口的實(shí)現(xiàn)2
sample-auth-project : 運(yùn)行bundle1和bundle2的主程序

bundle的實(shí)現(xiàn)

  1. 可以基于doraemon-project-archetype來構(gòu)建你的代碼骨架
  2. 生成的doraemon-bundle目錄結(jié)構(gòu)如圖2


    圖2

bundle 的 pom.xml關(guān)鍵依賴如下:

...

    <dependencies>
        <!--業(yè)務(wù)的基本依賴 -->
        <dependency>
            <groupId>io.github.qianxingchuan.framework</groupId>
            <artifactId>sample-auth-facade</artifactId>
        </dependency>
        <!--每個(gè)bundle的依賴,每個(gè)bundle 必須要有一個(gè) io.github.qianxingchuan.framework.doraemon.BundleService實(shí)例 -->
        <dependency>
            <groupId>io.github.qianxingchuan.framework</groupId>
            <artifactId>doraemon-facade</artifactId>
            <version>0.1-RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
    </dependencies>
...
</project>

bundle內(nèi)部的實(shí)現(xiàn),不限制框架,因?yàn)閐oraemon在運(yùn)行每個(gè)bundle的時(shí)候是互相隔離的,但是每個(gè)bundle必須要有一個(gè)類來實(shí)現(xiàn)io.github.qianxingchuan.framework.doraemon.BundleService,并且配置到 bundle.properties

bundle.properties配置如下:

init-class=io.github.qianxingchuan.doraemon.sample.auth.run.SampleBundleRun
skip-class=io.github.qianxingchuan.doraemon.sample.facade.AuthFacade

init-class 的意思就是bundle在初始化會自動執(zhí)行這個(gè)里面的doIt方法
skip-class 的意思是該class不會由bundle的類加載器來加載

所以按照我們圖1的表述,這個(gè)配置就是SampleBundleRun由bundle1的模塊類加載器來加載,AuthFacade則由Application所在的類加載器來加載。

所有的代碼寫完之后,通過mvn clean compile package,即可生成一個(gè) .zip 的bundle文件。

bundle運(yùn)行

參照sample-auth-project工程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。