【背景】
之前在領英上讀到一篇軟文,《Managing Software Dependency at Scale》,講述了領英是如何處理模組之間的依賴解析,以及如何去更好的處理依賴關係以及依賴管理。感覺在一家多產品的公司,在產品有可能相互依賴的情況下,都應該有這麼一套系統,來進行依賴關係的管理以及維護。
所以,花費了一天的時間在GitHub上都沒有找到可以正常執行的專案之後,決定參照上面的幾個現有的實現方式,自己實現一套。
【思考】
首先,簡單講述一下為什麼需要這樣一個系統?
不知道大家有沒有思考,在一個可能有上千個模組/產品的公司,對於模組之間有較多相互依賴的情況,以下問題該如何解決:
- 我們把一個生命週期結束的元件移除之後,會有什麼影響?
- 在程式碼修改之後,我們應該run哪些dependency測試例?
- 在一個已部署的系統中,我們最終要使用哪個version的模組?
- 是否有人使用高危版本的庫?
以上問題,其核心原則就是,在所有產品的整個開發週期中,在修改某個依賴的同時,不會對其他產品造成任何影響。
【如何儲存依賴關係】
之前的時候,考慮過使用鍵值對資料庫和非關係型資料庫去儲存相關的依賴,但是效果都不理想,最後選用了圖資料庫(Neo4J).
這樣做有三個好處:
- 對於任意模組,不論其是否依賴其他模組,或是被其他模組依賴,都可以很直觀得在資料庫中體現;
- 對於任意模組,其依賴的下級模組和上級模組可以快速地匯出;
- 對於跨級依賴可以有更好的體現。
【設計】
程式碼結構如下:
在Model中,Dependency對映pom檔案中的dependency,Project對映產品,Neo4jConn對映資料庫資訊。
Service中,GraphBuilder主要處理產品以及模組之間的相互依賴關係,Neo4JHandler主要處理與資料庫相關的具體操作。
Util裡面,Finder繼承SimpleFileVisitor,處理一些路徑的匹配工作,PomFileFinder利用Finder,尋找所有的pom檔案並返回列表,XMLConverter利用javax.xml的工具類處理具體的xml檔案。
DependencyManager作為整個程式的入口,對外提供服務。
【使用】
首先在工程目錄下執行mvn clean install/package打包;
然後進入target目錄下執行:
java -jar dependency-manager-0.0.1-SNAPSHOT-jar-with-dependencies.jar D:/workspace/so bolt://localhost:7687 neo4j neo4j Module org.spring*
第一個引數指定pom檔案路徑(預設遞迴到20層,超過無法識別到);
第二個引數指定資料庫的url,第三個引數指定資料庫使用者名稱,第四個引數指定資料庫密碼;
第五個引數指定需要匯出依賴關係的是產品還是模組,如果指定模組,會將所有滿足條件的模組全部匯出,如果只指定產品,則只匯出所有產品之間的依賴關係。
第六個引數指定模組需要滿足的條件,可以指定字首,中綴,字尾,如spring*,指所有以spring開頭的包,這種方式可以去掉一些我們不關注的包,比如org相關的,spring框架相關的,可以大大降低我們的工作量。
當然,你也可以直接執行:
java -jar dependency-manager-0.0.1-SNAPSHOT-jar-with-dependencies.jar
命令來獲取幫助。
如圖所示則執行成功:
【結果】
執行結果可以在Neo4J中檢視:
紅色為產品,褐色為模組。
【優化】
當然了,這只是一個小應用,還有很大的發展空間,之後會有如下幾個改進:
- Dependency Manager UI視覺化,可以直接將結果通過頁面的方式展示給使用者;
- 通過自動化的方式更新依賴關係;
- 根據模組使用情況自動發出迴圈依賴以及廢棄庫使用的警告;
- 可以跨平臺使用,不侷限於Maven管理的Java專案。
當然,也希望有同樣想法的小夥伴可以提提設計上的意見,或者閱讀過原始碼之後有改進的思路給到,都不勝榮幸。
【獲取】
GitHub地址:https://github.com/liufarui/dependency-manager