maven自定義插件 ---- maven高級篇

maven簡介

Maven 作爲一個優秀的項目管理工具,其插件機制爲其功能擴展提供了非常大的便捷性。雖然說大多數情況下,我們可能不太會自己去編寫 Maven 插件,但不排除在某些特殊的情況下,我們需要去完成一個自己的插件,來協助我們處理某些比較通用的事情。正好,最近有一些需求可能需要對 Drools 的一個 Maven 插件進行擴展,所以學習一下 Maven 的插件編寫。

Maven 插件的命名規範

一般來說,我們會將自己的插件命名爲 -maven-plugin,而不推薦使用 maven–plugin,因爲後者是 Maven 團隊維護官方插件的保留命名方式,使用這個命名方式會侵犯 Apache Maven 商標。

什麼是 Mojo?

Mojo 就是 Maven plain Old Java Object。每一個 Mojo 就是 Maven 中的一個執行目標(executable goal),而插件則是對單個或多個相關的 Mojo 做統一分發。一個 Mojo 包含一個簡單的 Java 類。插件中多個類似 Mojo 的通用之處可以使用抽象父類來封裝。

創建 Mojo 工程

這裏,我們使用 Idea 作爲開發工具進行講解,創建工程選擇 Maven,然後在模板中找到 maven-archetype-mojo(其實也可以不用選擇任何模板,直接下一步),點擊下一步,輸入對應的參數,如:com.sm/hello-maven-plugin/0.0.1,最後點擊完成即可創建一個簡單的 Mojo 工程。

配置pom.xml

創建完成後,工程內會生成對應的 pom.xml 文件。其內容比較簡單,與普通 Maven 工程的 pom.xml 基本一致,只是自動添加了對 maven-plugin-api 的依賴,這個依賴裏面會包含一些 Mojo 的接口與抽象類,在後續編寫具體的 Mojo 時再進行詳細講解。

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-plugin-api</artifactId> // maven插件api接口
  <version>2.0</version>
</dependency>

<dependency>
  <groupId>org.apache.maven.plugin-tools</groupId>
  <artifactId>maven-plugin-annotations</artifactId> // maven註解
  <version>3.1</version>
</dependency>

與普通 pom.xml 文件一個重要的不同之處是它的打包方式:

<packaging>maven-plugin</packaging>

簡單 Mojo 的創建

工程創建完畢後,我們開始 Mojo 創建之旅,上面提到過 Mojo 是一個簡單的 Java 類,那我們創建第一個 Mojo 類用於打印一行輸出。

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
/**
 * @goal hello
 */
public class HelloMojo extends AbstractMojo {

    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("hello world");
    }

}

觀察一下這個類,我們發現它繼承了 AbstractMojo 這個抽象類,並實現了 execute() 方法,該方法就是用來定義這個 Mojo 具體操作內容,我們只需要根據自己的需要來編寫自己的實現即可。

Mojo 操作的實現我們瞭解了,那怎麼讓 Maven 知道這是一個 Mojo 而不是一個普通的 Java 類呢?這裏,就需要說一下 Mojo 的查找機制了,在處理源碼的時候,plugin-tools 會把使用了 @Mojo 註解或 Javadoc 裏包含 @goal 註釋的類來當作一個 Mojo 類。在上面的例子中,我們使用了 Javadoc 的方法來聲明一個 Mojo。同樣我們也可以使用 @Mojo 註解來進行聲明:

@Mojo(name = "hello")
public class HelloMojo extends AbstractMojo {

    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("hello world");
    }
}

運行自定義 Plugin

與使用其它插件類似,我們需要在 pom.xml 文件中引入插件。正常情況應該是先將編寫的maven插件上傳到nexus私服,然後再配置,這樣就會從nexus私服上下載
nexus私服 教程請參考:

1. nexus的linux安裝包: https://download.csdn.net/download/miracle_8/12056904
2. 安裝: https://blog.csdn.net/BuFanQi_Info/article/details/81317844
3. 上傳jar:  https://blog.csdn.net/u013887008/article/details/79429973
4. 刪除jar: https://blog.csdn.net/u013958151/article/details/80311462

當然考慮到maven的加載機制是先從本地的repository加載的,可以直接在本地repository按照maven的目錄配置對應的數據目錄並上傳自定義插件包即可

之後就可以在本地的項目中添加自定義插件的引用了

<build>
    <plugins>
        <plugin>
            <groupId>com.sm</groupId>
            <artifactId>hello-maven-plugin</artifactId>
            <version>0.0.1</version>
        </plugin>
    </plugins>
</build>

驗證

先執行命令:

mvn install

然後執行:

mvn com.sm:hello-maven-plugin:0.0.1:hello

即可看到輸出:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building hello-maven-plugin Maven Mojo 0.0.1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- hello-maven-plugin:0.0.1:hello (default-cli) @ hello-maven-plugin ---
hello world
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.249 s
[INFO] Finished at: 2017-03-26T12:59:47+08:00
[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------

縮短執行命令
在剛纔運行插件的時候,我們使用全量的插件指引,但這個實在是太長太繁瑣了,那我們是否可以縮短我們的執行命令呢?答案肯定是可以的,如果你想要執行的是你本地庫中最新版本的插件,那麼你可以刪除掉版本號;如果你的命名滿足前面提及的兩種命令方式,你可以直接使用插件名及 goal 名來運行對應的插件,如:

mvn sm:hello

你會得到與之前完全一樣的結果。

綁定 Maven 執行週期

你還可以將插件配置爲將特定目標,從而附加到構建生命週期中的某個特定階段。如:

<build>
    <plugins>
        <plugin>
            <groupId>com.sm</groupId>
            <artifactId>hello-maven-plugin</artifactId>
            <version>0.0.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>hello</goal>
                    </goals>
                    <phase>package</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

繼承AbstractMojo 的類中,參數可以通過命令賦值,例如:

/**
 *
 * @goal echo
 * @phase process-sources
 */
public class Hello extends AbstractMojo {

    /**
     * @parameter property="echo.message" default-value="Hello World..."
     */
     //@Parameter(defaultValue="${project}", readonly=true)
    private String message;

    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("hello world");

        getLog().info("hello mymojo : "+message);
    }

}

其中註釋就是maven插件很重要的元數據

/**
 * @goal CustomMavenMojo:表示該插件的服務目標
 * @phase compile:表示該插件的生效週期階段
 * @requiresProject false:表示是否依託於一個項目才能運行該插件
 * @parameter expression="${name}":表示插件參數,使用插件的時候會用得到 express在最新的maven中已經被替代了
 * @required:代表該參數不能省略
 */

執行:

mvn com.sm:hello-maven-plugin:0.0.1:hello -Decho.message="Fuck shit "

(MyMojo類中的message 參數的javadoc註釋是 echo.message, 通過命令賦值時,需要傳入
-Decho.message=XXX 這種形式 )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章