Maven插件
1.1、插件(plugin)

Maven实际上就是一个插件系统,它的所有实际工作都是由插件来完成的。

1.2、目标(goal)

Maven里,把每一个工作都称为目标(goal)。

Maven中的目标(goal)等同于Antgradle中的任务(task)。

一个插件是一组工作的集合。也就是说,一个插件可以干不止一件工作,每个插件会有一个或者多个目标。

1.3、如何执行一个目标
1.3.1、mvn ${groupId:artifactId:version:goal}

有的目标是不需要依赖一个项目的,也就是不需要依赖一个pom.xml配置文件。 这种目标就可以直接在命令行下执行。这种执行方式与生命周期无关。

示例:

mvn org.apache.maven.plugins:maven-help-plugin:2.1:describe -Dplugin=compiler

说明:

org.apache.maven.plugins:maven-help-plugin:2.1是定位了一个插件。

describe是此插件的一个目标。

-Dplugin=compiler是此目标的参数。

1.3.2、mvn ${goalPrefix}

在命令行方式下以mvn groupId:artifactId:version:goal方式执行一个目标是及其不方便的, 因为一般的groupIdartifactId都会很长,字符太多。 所以就发明了目标前缀(goalPrefix)的概念,其实,就是给groupId:artifactId:version起了一个简短的别名而已。

比如,org.apache.maven.plugins:maven-help-plugin:2.1插件的目标前缀是help, 上面那个命令就可以简化为如下:

mvn help:describe -Dplugin=compiler

这样就写起来容易多了。

我们如何知道一个插件的目标前缀(goalPrefix)是什么?目标前缀(goalPrefix)artifactId之间存在关系吗?

Maven的核心插件都是官方团队开发和维护的,这些插件的groupId都是org.apache.maven.pluginsartifactId的格式都是maven-xx-plugin,这些插件的目标前缀(goalPrefix)都是xx。其他的插件没有这种规律。

1.3.3、mvn ${phase}

示例:

mvn compile

此命令中的compiledefault生命周期compile阶段。

一个生命周期阶段是如何执行到目标的呢? 我们自然就能想到,肯定是将一个插件的目标与这个生命周期阶段进行了绑定, 这样才顺藤摸瓜找到干活儿的人的呀。那么如何绑定这种关系呢?

绑定有2种方式:

显式绑定:在pom.xml配置文件中进行配置, 将某个插件的目标与Maven生命周期的某个阶段(Phase)进行绑定。

隐式绑定:在编写插件的时候就绑定好了,不需要我们自己配置。 例如maven-compiler-plugin插件默认将compile目标与default生命周期compile阶段进行了绑定, 我们自己并没有在pom.xml配置文件中进行这种绑定关系的配置, 但是我们执行mvn compile命令的时候,却自动使用了maven-compiler-plugin插件的compile目标进行工作的。

1.4、Maven插件列表

多年来Maven社区积累了大量的经验,并随之形成了一个成熟的插件生态圈。

Maven官方有两个插件列表:

groupId说明
org.apache.maven.plugins这些插件最为成熟
org.codehaus.mojo这些插件没有那么核心,但也有不少十分有用
1.5、常用的Maven插件

想更高效率地使用Maven,了解一些常用的插件还是很有必要的,这可以帮助你避免一不小心重新发明轮子。

1.6、自定义Maven插件

1、使用maven-archetype-plugingenerate目标创建Maven工程:

mvn archetype:generate

这里是让你选择你要创建的工程的模板,输入maven-archetype-mojo,然后回车。

这里是让你进一步确认,输入1,然后回车。

这里是让你选择使用maven-archetype-mojo的哪个版本,默认是5,直接回车。

这里是让你输入你的工程的信息,输入后回车。

工程创建成功。

2、进入工程目录,查看工程目录结构如下:

3、查看pom.xml的内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.fpliu</groupId>
    <artifactId>maven-newton-plugin</artifactId>
    <packaging>maven-plugin</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>maven-newton-plugin Maven Mojo</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

实际上,就是配置了一下我们自己的工程的坐标信息和依赖了2个jar包。

4、创建IDE的工程信息(方便在IDE中开发)

创建Eclipse的工程信息:

mvn eclipse:eclipse

创建IDEA的工程信息:

mvn idea:idea

5、查看src/main/java/com/fpliu/newton/MyMojo.java的内容:

这里的注释中的注解是不能随意删除的,他们都是有用的,会被打包工具读取。

@goal touch就是声明此类是一个目标的执行类,并且该目标的名字为touch

@phase process-sources就是声明此目标与process-sources这个生命周期阶段绑定。

6、打包:

mvn clean package

生成的插件为target/maven-newton-plugin-1.0-SNAPSHOT.jar

7、使用unzip解压它:

unzip maven-newton-plugin-1.0-SNAPSHOT.jar -d xx

8、查看解压后的目录结构:

9、查看META-INF/maven/plugin.xml的内容:

打包后的信息都记录在这里呢。mvn命令会读取这些信息。

至此,您肯定明白了mvn命令的工作机制了。

10、安装到本地Maven仓库中:

mvn clean install

11、使用该插件。在你的pom.xml中加入如下的配置:

<build>
    <plugins>
        <plugin>
            <groupId>com.fpliu</groupId>
            <artifactId>maven-newton-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
        </plugin>
    </plugins>
</build>

你可以运行下面的命令了:

mvn com.fpliu:maven-newton-plugin:1.0-SNAPSHOT:touch
mvn newton:touch
mvn process-sources

12、如果想要让其他人使用的话,你需要将此插件发布到Maven仓库中。