相關代碼利虫,見我的開源項目:
https://github.com/qianxingchuan/doraemon
簡介
2017年挨厚,我在菜鳥物流云這個部門做了一個叫做Asgard的網(wǎng)關,當時為了快速實現(xiàn)糠惫,只適配了阿里巴巴的技術棧體系疫剃,比如鑒權的部分,直接把菜鳥的賬號系統(tǒng)接入的代碼固化在網(wǎng)關硼讽;再比如調用服務的部分巢价,直接把泛化調用HSF的代碼固化在網(wǎng)關。這些固化代碼的方式,對于Asgard的可擴展性和靈活性都造成了無比巨大的限制壤躲。
從菜鳥離職之后城菊,在2019年5月,在vivo做關于云存儲相關的項目碉克,vivo的基礎設施不是特別完美凌唬,所以存在很多重復勞動,比如幾乎每個web應用都會寫一套一模一樣的app鑒權漏麦、web鑒權客税,以及通用的cors的配置。這一點我非常不爽唁奢,所以決定在vivo重新把Asgard寫一遍霎挟,這次重寫,必定完善之前菜鳥物流云時期沒有時間做的一些事情麻掸,比如高度可自定義每個調用階段酥夭,再比如網(wǎng)關必須要支持響應式、全異步脊奋,以及支持websocket等等熬北。
既然要實現(xiàn)高度自定義,那么我們需要有一套高度可插拔的plugin處理框架诚隙,osgi太重了讶隐,我不想我們的應用有太多這樣的依賴,以及發(fā)布規(guī)范; 螞蟻金服有一套開源的sofa-ark久又,也能滿足我的要求巫延,但是對于我來說,還是不夠輕量級地消,我其實只要能在網(wǎng)關應用內部可以獨立每個plugin即可炉峰,如圖1:
本文重點介紹我基于Java類加載器實現(xiàn)的一個輕量級模塊隔離框架:Doraemon。
在同一個JVM里面脉执,我們的應用程序可以調用任意一個bundle的export出來的實例疼阔,bundle互相之間不可見。
Doraemon快速使用
實現(xiàn)基于鑒權接口的不同實現(xiàn)
樣例工程見doraemon-sample
主要工程:
sample-auth-facade : 鑒權的接口定義
sample-auth-bundle1 : 基于鑒權接口的實現(xiàn)1
sample-auth-bundle2 : 基于鑒權接口的實現(xiàn)2
sample-auth-project : 運行bundle1和bundle2的主程序
bundle的實現(xiàn)
- 可以基于doraemon-project-archetype來構建你的代碼骨架
-
生成的doraemon-bundle目錄結構如圖2
bundle 的 pom.xml關鍵依賴如下:
...
<dependencies>
<!--業(yè)務的基本依賴 -->
<dependency>
<groupId>io.github.qianxingchuan.framework</groupId>
<artifactId>sample-auth-facade</artifactId>
</dependency>
<!--每個bundle的依賴半夷,每個bundle 必須要有一個 io.github.qianxingchuan.framework.doraemon.BundleService實例 -->
<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內部的實現(xiàn)婆廊,不限制框架,因為doraemon在運行每個bundle的時候是互相隔離的巫橄,但是每個bundle必須要有一個類來實現(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í)行這個里面的doIt方法
skip-class 的意思是該class不會由bundle的類加載器來加載
所以按照我們圖1的表述淘邻,這個配置就是SampleBundleRun由bundle1的模塊類加載器來加載,AuthFacade則由Application所在的類加載器來加載湘换。
所有的代碼寫完之后宾舅,通過mvn clean compile package敬尺,即可生成一個 .zip 的bundle文件。
bundle運行
參照sample-auth-project工程