最近筆者在做倉庫庫存的縮減,首先考慮的是基於靜態掃瞄的縮減,我嘗試使用了很多工具來優化庫存,比如PMD、Idea自帶的檢查功能、findbugs等。 但無一例外,要麼它們過於“保守”,只給出掃瞄結果,卻無法實現一鍵優化,要麼直接有問題(這裡特指idea2023)。1.5 專業檢查功能掃瞄問題列表中未使用的宣告)。對於懶惰的人來說,手動點選乙個按鈕幾百次和坐牢沒什麼區別,所以他寫了乙個工具,一鍵修改大部分指定的優化點(具體來說,就是用龍目島的@data註解來代替顯式的getter setter和tostring方法)。
本文內容主要分為三個部分,第一部分詳細描述了工具實現的思路,第二部分將簡要介紹開源工具j**aparser,第三部分提供了該工具的使用方法。
在翻閱歷史時,我發現許多工程儲存庫中的許多類仍然用於生成 getter setter,如果使用 Lombok 的 @data 註解來替換它們,它可以帶來幾個好處。
顯然,它使它更乾淨,減少了體積,並減少了將來新增新字段所帶來的重複工作。
提高了可讀性,當其他同事參與開發時,無需檢查 getter setter 中是否有邏輯。
避免遺漏,降低犯錯的風險,因為其他同事的介面資料省略了編寫get方法,這增加了大量的溝通成本。
回顧過去,讓我們看一下編寫乙個工具所需的步驟,該工具可以對整個專案中的所有類進行全面掃瞄,並用 lombok 替換帶有“無特殊邏輯”的 getter 和 setter。
1.掃瞄整個專案**,可以是多模組專案。
2.閱讀“.j**a“檔案。
3.篩選掉不需要的類,例如介面、沒有欄位的類(很可能是服務)、帶注釋的宣告等。
4.要刪除 getter setter 方法,需要確定 get 和 set 方法中是否有任何特殊邏輯。
5.用 @data 注釋類並引入 lombok 包。
6.將修改後的內容寫入 j**a 檔案。
下面介紹了每個步驟的實現。
工程掃瞄相對簡單,給出乙個專案路徑,然後遞迴呼叫它,過濾掉所有路徑。 j**a 檔案。
private static list scanj**afiles(file file) for (file f : files) if (file.getname().endswith(".j**a")) return result; }
一旦你有了所有檔案的列表,你就需要處理它們。
1.篩選出沒有欄位的類。
2.篩選出已使用 lombok 註解的類。
3.確定是否存在顯式 getter setter(請注意,布林型別的字段需要特殊處理)。
4.確定 getter setter 是否是簡單的返回和賦值操作。
5.刪除 getter setter。
6.新增@data批註。
7.新增了龍目島包的介紹。
這裡我們使用 github 上的開源工具 j**aparser 來解析、提取、刪除和新增新內容到類中,這將在下一章中介紹。
這有點簡單粗暴,直接用equals來確定方法體,其實j**aparser提供了乙個更完整的API來分析語義。
清理完 ** 後,需要將內容更新到 j**a 檔案中,並且 compilationunit 重寫了 tostring 方法,可以支援直接將 ** 轉換為字串的形式。
J**Aparser 是乙個開源的 J**a 源分析工具,它提供了一系列簡單的 API 來解析、修改和生成j**a **
例如,我們可以使用 j**aparser 輕鬆執行以下操作:
1.分析**中的類、方法、欄位等元素,提取類的繼承關係、方法的引數、返回型別等。
2.更改原始碼,例如重新命名方法、修改方法主體、新增或刪除行等。
3.您可以使用它來生成片段,例如建立新的類、方法或字段,或生成文件。
在上一章中,我們使用了資料提取和原始碼替換功能。 這是 j**aparser 的鏈結:
官方網站: github: wiki:wiki.git j**adoc:j**aparser 的主要元件包括以下元件:
1.詞法分析器:詞法分析器用於讀取源文字並將其分解為一系列標記,例如關鍵字、識別符號、文字、運算子等。 這是解析過程的第一步。
通常我們不需要顯式呼叫它,j**aparser 隱藏了實現的具體細節,呼叫方只需要使用開放的 API 即可完成原始碼到 AST 的轉換。 有關詳細資訊,您可以翻閱 comgithub.j**aparser.generatedj**aparser
2.解析器:解析器接收詞法分析器生成的標記,並按照 J**A 語言的語法規則,將它們組合成各種句法結構,如表示式、語句、類定義等。 此過程將生成抽象語法樹 (AST)。
com.github.j**aparser.j**aparser 是觸發解析過程並生成 AST 最常用的類,在上一節中,使用 staticj**aparser 將原始檔解析為 CompilationUnit,並在 parse 方法中使用 j**aparser 來完成此解析過程。
3.AST(抽象語法樹):AST 是 j**aparser 的核心資料結構,它以分層方式表示源的結構。 AST 由一系列節點組成,每個節點表示源中的乙個元素,例如類、方法、字段、表示式等。 每個節點都包含有關元素的資訊,例如名稱、型別、修飾符等。
AST 是後續操作(例如遍歷、分析、修改)的基礎,也是消費者操作最多的類。 上一節中使用的 com.github.j**aparser.ast.CompilationUnit 是乙個非常重要的類,它表示 ja 原始檔的根節點,是這個結構的抽象表示,包含整個檔案的結構,例如:
包裝宣告
進口
型別宣告,可以是類、介面、列舉或批註。
評論
任何頂級批註。
通過操作 compilationunit 提供的公共方法,您可以訪問和修改檔案中的元素。 包括:
獲取和設定包宣告。
獲取和新增匯入宣告。
獲取和新增型別宣告。
獲取和新增評論。
使用訪客模式遍歷 AST 中的節點。
4.訪客:顧名思義,這是乙個以訪客模式為設計理念的元件,可用於遍歷和操作 AST。 開發人員可以編寫自定義訪問者,通過遍歷 AST 訪問特定型別的節點,並執行分析、重構和生成等任務。
com.github.j**aparser.ast.visitor.genericvisitor 和 comgithub.j**aparser.ast.visitor.這兩個訪問器提供預設實現,如果需要自定義訪問器,可以繼承它們來實現自己的業務邏輯。
5.印表機:這也很容易理解,因為印表機用於將 AST 轉換回 Ja 源的字串表示形式。 它可以將修改後的 AST 列印回原始原始檔,或將 AST 列印為格式化字串。 上一章末尾提到的 CompilationUnit 重寫的 Tostring 方法,實際上是使用印表機將 AST 轉換為源字串。
以上部分元件是 j**aparser 的核心和常用部分,當然 j**aparser 也提供了一些方便的工具和用法,筆者沒有接觸過,有需要的讀者可以自己翻閱文件。
第一章提到的 JAR 包和原始碼已經上傳到私有伺服器,可以直接通過 m**en 外掛程式執行。
com.jd.omni.opdd lombok-replace 0.0.1-snapshot
org.codehaus.mojo exec-m**en-plugin 3.0.0 j**a com.jd.omni.opdd.tools.lombok.lombokconverter ../../pop-jingme-customs
外掛程式中的引數節點需要替換為專案的路徑,可以是絕對路徑,也可以是相對路徑。
執行 mvn exec:j**a
可以在控制台中看到:
使用工具完成處理後,一定要檢查構建中是否存在編譯錯誤,雖然刪除操作時做了比較嚴格的驗證,但一些特殊的變數名可能不考慮,這部分問題可以通過編譯來檢查。
此外,對於不引用龍目島的模組,您需要手動新增依賴項。
* 重建應該像手術刀一樣,快速、準確、無情,正如所謂君子一樣,在事物上是善偽的。 這篇文章主要起到扔磚和玉的作用,重點介紹j**aparser,作者寫的這個小工具很簡單,我還寫了b-paas一鍵生成矩陣JSON,根據錯誤碼定義一鍵生成i18n檔案,大部分都不難。
如果換個角度思考,可以通過將 j**apaser 與其他平台提供的開放 API 結合起來做一些有趣的事情,比如結合 jsf、ump 和 pfinder 的 API,實現無需呼叫方的方法清理。
除了重構之外,還可以在拿到語法樹後做一些視覺化工具,參考之前發布的謝曉寫的“視覺化”。
作者:京東零售 譚磊.
*:京東雲開發者社群**轉載請註明**。