讀古今文學網 > Maven實戰 > 17.2 案例:編寫一個用於代碼行統計的Maven插件 >

17.2 案例:編寫一個用於代碼行統計的Maven插件

為了便於大家實踐,下面將詳細演示如何實際編寫一個簡單的用於代碼行統計的Maven插件。使用該插件,用戶可以瞭解到Maven項目中各個源代碼目錄下文件的數量,以及它們加起來共有多少代碼行。不過,筆者強烈反對使用代碼行來考核程序員,因為大家都知道,代碼的數量並不能真正反映一個程序員的價值。

要創建一個Maven插件項目,首先使用maven-archetype-plugin命令:

然後選擇:

輸入Maven坐標等信息之後,一個Maven插件項目就創建好了。打開項目的pom.xml可以看到如代碼清單17-1所示的內容。

代碼清單17-1 代碼行統計插件的POM

Maven插件項目的POM有兩個特殊的地方:

1)它的packaging必須為maven-plugin,這種特殊的打包類型能控制Maven為其在生命週期階段綁定插件處理相關的目標,例如在compile階段,Maven需要為插件項目構建一個特殊插件描述符文件。

2)從上述代碼中可以看到一個artifactId為maven-plugin-api的依賴,該依賴中包含了插件開發所必需的類,例如稍後會看到的AbstractMojo。需要注意的是,代碼清單17-1中並沒有使用默認Archetype生成的maven-plugin-api版本,而是升級到了3.0,這樣做的目的是與Maven的版本保持一致。

插件項目創建好之後,下一步是為插件編寫目標。使用Archetype生成的插件項目包含了一個名為MyMojo的Java文件,我們將其刪除,然後自己創建一個CountMojo,如代碼清單17-2所示。

代碼清單17-2 CountMojo的主要代碼

首先,每個插件目標類,或者說Mojo,都必須繼承AbstractMojo並實現execute()方法,只有這樣Maven才能識別該插件目標,並執行execute()方法中的行為。其次,由於歷史原因,上述CountMojo類使用了Java 1.4風格的標注(將標注寫在註釋中),這裡要關注的是@goal,任何一個Mojo都必須使用該標注寫明自己的目標名稱,有了目標定義之後,我們才能在項目中配置該插件目標,或者在命令行調用之。例如:

創建一個Mojo所必要的工作就是這三項:繼承AbstractMojo、實現execute()方法、提供@goal標注。

下一步是為插件提供配置點。我們希望該插件默認統計所有Java、XML,以及properties文件,但是允許用戶配置包含哪些類型的文件。代碼清單17-2中的includes字段就是用來為用戶提供該配置點的,它的類型為String數組,並且使用了@parameter參數表示用戶可以在使用該插件的時候在POM中配置該字段,如代碼清單17-3所示。

代碼清單17-3 配置CountMojo的includes參數

代碼清單17-3配置了CountMojo統計Java和SQL文件,而不是默認的Java、XML和Properties。

代碼清單17-2中還包含了basedir、sourceDirectory、testSourceDirectory等字段,它們都使用了@parameter標注,但同時關鍵字expression表示從系統屬性讀取這幾個字段的值。${project.basedir}、${project.build.sourceDirectory}、${project.build.testSourceDirectory}等表達式讀者應該已經熟悉,它們分別表示了項目的基礎目錄、主代碼目錄和測試代碼目錄。@readonly標注表示不允許用戶對其進行配置,因為對於一個項目來說,這幾個目錄位置都是固定的。

瞭解這些簡單的配置點之後,下一步就該實現插件的具體行為了。從代碼清單17-2的execute()方法中大家能看到這樣一些信息:如果用戶沒有配置includes則就是用默認的統計包含配置,然後再分別統計項目主代碼目錄、測試代碼目錄、主資源目錄,以及測試資源目錄。這裡涉及一個countDir()方法,其具體實現如代碼清單17-4所示。

代碼清單17-4 CountMojo的具體行為實現

這裡簡單解釋一下上述三個方法:collectFiles()方法用來遞歸地收集一個目錄下所有應當被統計的文件,countLine()方法用來統計單個文件的行數,而countDir()則借助上述兩個方法統計某一目錄下共有多少文件被統計,以及這些文件共包含了多少代碼行。

代碼清單17-2中的execute()方法包含了簡單的異常處理,代碼行統計的時候由於涉及了文件操作,因此可能會拋出IOException。當捕獲到IOException的時候,使用MojoExecutationException對其簡單包裝後再拋出,Maven執行插件目標的時候如果遇到MojoExecutationException,就會在命令行顯示「BUILD ERROR」信息。

代碼清單17-4中的countDir()方法的最後一行使用了AbstractMojo的getLog()方法,該方法返回一個類似於Log4j的日誌對象,可以用來將輸出日誌到Maven命令行。這裡使用了info級別的日誌告訴用戶某個路徑下有多少文件被統計,共包含了多少代碼行,因此在使用該插件的時候可以看到如下的Maven輸出:

使用mvn clean install命令將該插件項目構建並安裝到本地倉庫後,就能使用它統計Maven項目的代碼行了。如下所示:

如果嫌命令行太長太複雜,可以將該插件的groupId添加到settings.xml中。如下所示:

現在Maven命令行就可以簡化成:

這裡面的具體原理可參考7.8.4節。