一種簡單的低侵入性的組件化方案

本組件化方案已開源在github,歡迎轉載和star。github.com/beyondxia/m…java

傳統組件化方案問題

    上篇中咱們對傳統的組件化方案的實現原理進行了簡單的介紹,以及對其優缺點進行了相應的分析。針對接口通訊機制的方案,有以下缺點:
a、須要提供一個公共的目錄或者公共模塊用做爲服務層,全部接口文件和中間共享的文件都須要手動拷貝至服務層。
b、組件若須要提供服務,除了自己的實現類,還須要提供一個或多箇中間接口文件,增長了開發量和組件集成的複雜度以及維護成本。
c、因爲服務實現類與服務接口存在依賴關係,因此業務方須要實現暴露的接口,並要實現具體須要暴露的業務功能。
d、全部的組件服務的註冊都須要手動進行,增長了開發量與風險。
e、與接口相關的一些中間類(特別model)也須要同步下沉至公共目錄。git

優化方案

1. APT生成接口文件

    針對不足點a和b,若是能夠自動生成並拷貝接口文件,那爲題就迎刃而解,那該如何作呢?
    咱們知道,APT(Annotation Processing Tool 的簡稱)能夠在代碼編譯期解析註解,生成新的Java文件,能夠減小手動的代碼輸入.
    本框架就是利用APT進行接口文件的自動生成。用戶要作的只是給須要暴露的服務以及服務中須要暴露的方法添加相應的註解(@ExportMethod),APT將根據註解自動生成接口。以下圖所示,Message即爲組件提供的服務類,IMessage爲生成的接口。github

2. javassist修改字節碼

    APT能夠生成對外暴露接口,那接下來咱們須要作的就是讓業務方實現該接口,並完成真正功能的實現,那又改如何作呢?
    其實從代碼層面看,咱們只須要Message類實現IMessage,因爲Message在IMessage接口生成前就已經由模塊內部實現,因此若是要修改Message,最好的方法仍是編譯階段修改Message.class字節碼。
    Javassist 是一個執行字節碼操做的庫。它能夠在一個已經編譯好的類中添加新的方法,成員,或者實現某個接口、繼承某個父類等。
    針對不足點c:Javassist恰好能夠知足咱們的需求,編譯階段經過修改字節碼,讓Message實現接口IMessage。這樣就實現了服務類Message與服務接口類IMessage的實現關係。json

    這樣還有一個好處:若服務類進行版本升級,框架會經過APT與gradle transform技術能夠對服務接口作到靜默自動同步,對組件開發者徹底無感知,開發者只需專一於開發本身的組件業務便可。數據結構

3. APT完成組件的蒐集和註冊

    針對不足點d:框架經過APT技術,對有ExportService註解標識的服務類進行收集,並在框架初始化的時候進行自動註冊,開發者徹底不須要參與註冊工做。而且咱們根據服務的使用場景以及頻率提供了不一樣的實例化時機,可根據組件的使用場景在註解上進行相應的配置便可。框架

4. 自定義BCDictionary代替傳統Model

    針對不足點e:咱們不提倡組件間以自定義的model傳輸數據,但傳輸複雜類型的數據類型又是不可避免的,固然能夠選擇現有的序列化方式傳輸,如json,但在序列化和反序列化時須要開發者作諸多繁瑣的操做。爲此,框架提供了一種簡單易用的的傳輸複雜類型數據類型的方式,極大程度上簡化了序列化與反序列化的操做。組件化

其餘問題:

若是組件間由於業務須要,須要共享複雜數據結構,如:post

    須要暴露一個自定義view。 從原則上來說,組件化設計不建議組件間共享複雜類型,即便有這類類型,更建議以通用數據下沉至base層的方式。 可是針對一個大型項目作組件化拆分的時候,有時必然要設計這類問題。針對這樣的問題,是須要手動拷貝文件至服務層。

    經過以上介紹的方案,框架基本上解決了接口通訊方式存在的缺點。大部分工做已經由框架在編譯階段完成,極大的減小了業務接入的成本,對代碼侵入性極小,使開發者能夠專一於組件功能的開發。gradle

上一篇:一種低侵入性的組件化方案 之 傳統組件化方案的問題優化

相關文章
相關標籤/搜索