相關(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:
本文重點(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)
- 可以基于doraemon-project-archetype來構(gòu)建你的代碼骨架
-
生成的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工程