Maven常用操作:插件的編寫和使用

前言

雖然,平時工作基本用不到自定義插件,但手動實現一遍還是很有必要.

這樣在配置和調用Maven插件時才能做到知其所以然.

所以本文的標題其實應該是:當我們在使用Maven插件時我們在使用什麼.

簡單來說,實現自定義插件,只需要繼承maven-plugin-api工程中的AbastractMojo並實現無參抽象方法execute即可.

不過這還不夠,因爲還需要考慮goal,phase和入參等操作.

有兩種方式來定義:

1️⃣ JavaDoc方式

2️⃣ 註解方式: 推薦使用.

實戰

使用IDEA可以很方便創建Maven插件項目:

在這裏插入圖片描述

命名項目:maven-plugin-demo;

等待工程生成完成,pom.xml已經引入maven-plugin-api,同時還生成了一個以JavaDoc方式實現的自定義插件示例(詳見文末附錄),故不再贅述,而是以註解形式實現一個自定義插件,它的作用很簡單,只是接收參數並打印.

首先引入包含註解的依賴(別忘了還有maven-plugin-api):

        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.5.2</version>
        </dependency>

繼承AbstractMojo:

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

@Mojo(name = "hello", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
public class AnnoMojo extends AbstractMojo {
    @Parameter(property = "hello.message", required = true, defaultValue = "${project.name}")
    private String[] message;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        System.out.println("hello " + String.join("", message) + "~");
    }
}

此時插件已經開發完成.

使用

引入依賴

    <build>
        <plugins>
            <plugin>
                <groupId>org.example</groupId>
                <artifactId>maven-plugin-demo</artifactId>
                <version>1.0-SNAPSHOT</version>
            </plugin>
        </plugins>
    </build>

執行mvn -Dhello.message=world,~~ demo:hello即可實現打印出hello world~~~的效果.

但一般不會這樣顯式地單獨調用,而是靠clean,compiledeployLifecycle來觸發,其觸發關鍵點在於插件所附着的phase,它們是有固定的先後順序的,可以參考官網.

            <plugin>
                <groupId>org.example</groupId>
                <artifactId>maven-plugin-demo</artifactId>
                <version>1.0-SNAPSHOT</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>hello</goal>
                        </goals>
                        <phase>process-sources</phase>
                    </execution>
                </executions>
                <configuration>
                    <message>every body! I'm Ryan</message>
                </configuration>
            </plugin>

此時執行mvn compile就會觸發插件的hello目標並打印輸出:hello every body! I'm Ryan~.

小結

  1. executions元素可以有多個execution,用來綁定一個phase和多個goal.
  2. configuration元素用來配置插件中定義的parameter

拓展

上節中提到了configuration用來靜態配置變量,而命令行可以動態設置,如果同時設置,誰的優先級更高呢?

答案是configuration元素.

同理,pom中定義的phase的優先級高於源碼中定義的defaultPhase

總結

  1. 命名規範: maven-plugin-XXX,可以簡化命令行調用:mvn XXX:$goal
  2. packaging:maven-plugin
  3. 建議使用註解形式實現,有提示而且排版舒服
  4. 參數包含空格時的,最好使用數組接收
  5. 命令行中的參數不會覆蓋pom.xml中已定義的參數
  6. 經常變動的參數不要在configuration中設置.

附錄

  1. 默認生成的源碼:

    /**
     * Goal which touches a timestamp file.
     *
     * @goal touch
     * @phase process-sources
     */
    public class MyMojo extends AbstractMojo {
        /**
         * Location of the file.
         *
         * @parameter expression="${project.build.directory}"
         * @required
         */
        private File outputDirectory;
    
        public void execute() throws MojoExecutionException {
    		// 此處忽略具體實現
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章