maven(八)-maven插件

一、插件目标

Maven的核心仅定义了抽象的生命周期,具体的任务是交由插件完成,插件以独立的构件形式存在。
对于插件本身,为了代码复用,它往往具备多个功能,而每个功能都统称为插件目标(Plugin Goal)。
如:maven-dependency-plugin,基于项目依赖做很多事情。
1 帮助分析项目依赖,帮助找出潜在的无用依赖;
2 列出项目依赖树,帮助分析依赖来源
3 列出项目已解析的依赖 等...
这些任务有很多代码可以复用。因此,这些功能聚集在一个插件中,每个功能就是一个插件目标。
插件目标使用语法:
1 完整命令 mvn groupId:artifactId:version:goal 如 mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:tree
2 简化version mvn groupId:artifactId:goal 如 mvn org.apache.maven.plugins:maven-dependency-plugin:tree
3 使用插件前缀 mvn 插件前缀:goal 如 mvn dependency:tree

二、插件绑定

Maven的生命周期与插件目标相互绑定,用以完成实际的构建任务。

三、内置绑定

为了使用户几乎不用任何配置就能构建Maven项目,Maven在核心为一些主要的生命周期阶段绑定了很多插件的目标,
当用户通过命令行调用生命周期时,对应的插件目标就会执行相应的任务。
如下图(default生命周期的阶段与插件目标的绑定关系由项目打包类型决定(packaging元素)下图以jar包构建为例

生命周期 阶段(phase) 内置插件 执行任务
clean pre-clean    
clean maven-clean-plugin:clean 删除项目的输出目录
post-clean    
default vaildate    
intianlize    
generate-sources    
proccess-sources    
generate-resoureces    
process-resources maven-resources-plugin:resources 复制主资源文件至主输出目录
compile maven-compiler-plugin:compile 编译主代码至主输出目录
process-classes    
generate-test-sources    
process-test-sources    
generate-test-resources    
process-test-resources maven-resources-plugin:testResources 复制测试资源文件至测试输出目录
test-compile maven-compiler-plugin:testCompile 编译测试代码至测试输出目录
process-test-classes    
test maven-surefire-plugin:test 执行测试用例
prepare-package    
package maven-jar-plugin:jar 创建项目jar包
pre-integration-test    
integration-test    
post-integration-test    
verify    
install maven-install-plugin:install 将项目输出构件安装到本地仓库
deploy maven-deploy-plugin:deploy 将项目输出构件安装到远程仓库
site pre-site    
site maven-site-plugin:site 生成项目站点
peo-site    
site-deploy maven-site-plugin:deploy 将项目站点部署到远程服务器上

Ps:空白的生命周期阶段,默认没有绑定任何插件,因此也没有任何实际行为
除默认打包类型jar外,常见的打包类型还有war、pom、maven-plugin、ear等。查看相关类型插件绑定官网http://maven.apache.org/guide...

四、自定义绑定

除了内置绑定以外,用户可以选择将某个插件目标绑定到生命周期的某个阶段,能让Maven项目在构建过程中执行更多更富特色的任务。
如maven-source-plugin:jar-no-fork,能够将项目主代码打成jar文件。将其绑定到default生命周期的verify阶段上,在执行完继承测试后和安装构件之前创建源码jar包。配置如下

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.0.1</version>
            <executions>    <!-- 插件执行配置 -->
                <execution>    <!-- executions下每个execution子元素可以配置执行一个任务 -->
                    <id>attach-sources</id>    <!-- 配置任务id -->
               <!-- <phase>verify</phase> -->  <!-- phase元素配置绑定生命周期阶段 -->
                    <goals>    <!-- 配置要执行的插件目标 -->
                        <goal>jar-no-fork</goal>
                    </goals>
                <execution>
            </executions>
        </plugin>
    </plugins>
</build>

完成自定义插件绑定后,运行mvn verify即可。
在上述代码中,注释了phase元素也能实现绑定,原因是很多插件目标在编写时已经定义了默认绑定阶段,可以使用maven-help-plugin查看插件详细信息,了解插件目标的默认绑定阶段。
mvn help:describe -Dplugin=groupId:artifactId:version

当插件目标绑定到不同的生命周期时,其执行顺序会由生命周期阶段的先后顺序决定。如果多个目标被绑定到同一个阶段,这些插件声明的先后顺序决定目标的执行顺序。

五、插件配置

完成插件目标与生命周期绑定后,用户还可以配置插件目标的参数,进一步调整插件目标所执行的任务,以满足项目的需求。几乎所有Maven插件目标都有一些可配置参数,可通过命令行和POM配置等方式来配置参数。

1)命令行插件配置

使用-D参数,并伴随一个参数名=参数值的形式,来配置参数
(命令行参数是由插件参数的表达式(Expression)决定,并非所有插件目标参数都有表达式,只能在POM中配置)
如maven-surrfire-plugin插件提供了一个maven.test.skip参数,当其值为true时,就会跳过执行测试。
mvn install -Dmaven.test.skip=true

2)POM中插件全局配置

并非所有插件参数都适合从命令行配置,有些参数的值从项目构建到项目发布都不会改变,或很少改变,在POM文件中一次性配置显然比重复在命令行输入要方便。
如mvan-compiler-plugin 可以配置全局参数 实现compile以及testCompile任务都能使用全局配置。

<build>
    <plugins>
        <plugin>
            <groupId>...</groupId>
            <artifactId>...</artifactId>
            <version>...</version>
            <configuration>    <!-- 声明插件全局配置 所有基于该插件目标的任务,都会使用这些配置 -->
                ...
            </configuration>
        </plugin>
    </plugins>
</builds>

3)POM中插件任务配置

除了为插件配置全局的参数,还可以为某个插件任务配置特定的参数。
如maven-antrun-plugin 可以配置插件任务参数,使run目标任务在不同生命周期输出不同的语句。

<build>
    <plugins>
        <plugin>
            <groupId>...</groupId>
            <artifactId>...</artifactId>
            <version>...</version>
            <executions>
                <execution>
                    <id>...</id>
                    <phase>...</phase>
                    <goals>
                        <goal>...</goal>
                    </goals>
                    <configuration>    <!-- 插件任务一配置 -->
                        ...
                    </configuration>
                </execution>
                <execution>
                    <id>...</id>
                    <phase>...</phase>
                    <goals>
                        <goal>...</goal>
                    </goals>
                    <configuration>    <!-- 插件任务二配置 -->
                        ...
                    </configuration>
                </execution>
                ...
            </executions>
        </plugin>
    </plugins>
</builds>

六、获取插件信息

仅仅理解如何配置使用插件是不够的,实现一个构建任务,用户需知道去哪找到合适的插件,并详细了解该插件的配置点。由于Maven的插件非常多,而且这其中大部分没有完善的文档,因此使用正确的插件并进行正确的配置,不容易。

1)在线插件信息

基本上所有的Maven插件都来自于apache和Codehaus。

apache 说明 官方插件,用户多,稳定性好
详细列表 http://maven.apache.org/plugi...
下载地址 http://repo1.maven.org/maven2...
Codehaus 说明 文档和可靠性相对较差,遇到问题,往往需要自己看源码
详细列表 http://mojo.codehaus.org/plug...
下载地址 http://repository.codehaus.or...

虽然并非所有插件都提供了完善的文档,但一些核心插件的文档还是非常丰富的。
一般来说,通过阅读插件在文档中的使用介绍和实例,就应该能够在自己的项目中很好地使用该插件。
当我们需要了解非常细节的目标参数时,就需要进一步访问该插件每个目标的文档。文档详细解释了该参数的作用、类型等信息。

2)使用maven-help-plugin插件

除了访问在线的插件文档之外,还可以借助maven-help-plugin来获取插件的详细信息。
执行maven-help-plugin的describe目标,指定要查询的插件的坐标,可查询插件的坐标,前缀(Goal Prefix),目标信息
mvn help:describe -Dplugin = (groupId:artifactId[:version] | Goal Prefix) -Dgoal = goal -Ddetail

七、从命令行调用插件

mvn -h 显示mvn命令帮助,可以看到如下信息:

usage:mvn [options] [<goal(s)]>] [<phase(s)>]
Options:
...

options表示可用的选项,除了选项之外,mvn命令后面可以添加一个到多个goal和phase,分别指插件目标和生命周期阶段。mvn命令可以激活生命周期阶段,从而执行那些绑定在生命周期阶段上的插件目标。也可以直接执行插件目标,因为有些插件目标不适用于生命周期阶段,如maven-help-plugin:describe。
直接执行插件目标语法 在上文中已提及,可在插件目标中查看。

八、插件解析机制

在命令行中执行插件目标,可使用插件前缀替代坐标,方便用户使用和配置插件。
Maven的这一特性是双刃剑,虽然它简化了插件的使用和配置,但如果出现问题,用户很难定位出问题的插件构件。
如mvn help:system 执行了什么插件。它的坐标是什么。这与Maven的插件解析机制有关。

1)插件仓库

与依赖构件一样,插件构件同样基于坐标存储在Maven仓库中,在需要的时候,Maven会先从本地仓库寻找插件,不存在则从远程仓库找到插件,下载到本地仓库使用。
插件的远程仓库不同于依赖的远程仓库,配置方式也不同,插件仓库配置如下:

<pluginRepositories>
    <pluginRepository>
        ...    <!-- 此处与依赖远程仓库配置一样,可参考阅读总结二查看 -->
    </pluginRepository>
    ...
</pluginRepositoties>

Maven内置了插件仓库指向中央仓库,并关闭了对SNAPSHOT的支持。
一般来说,中央仓库所包含的插件完全能够满足我们的需要,因此也不需要配置其他的插件仓库,只有在很少的情况下,项目使用的插件无法在中央仓库找到,或者自己编写了插件,可以参考上述配置,在POM中或settings.xml中 加入其他插件仓库。

2)插件的默认groupId

在POM中配置插件时,如果该插件是Maven官方插件(groupId为org.apache.maven.plugins),则可以省略groupId配置。
不推荐使用这一特性,只省略一行配置,但会让团队中不熟悉Maven的成员感到费解。

3)解析插件版本

同样为了简化插件的配置和使用,用户可没有提供插件的版本,Maven会自动解析插件版本。
首先,Maven在超级POM中为所有核心插件设定了版本,超级POM是所有Maven项目的父POM,所有项目都继承了这个超级POM配置。所以用户使用插件未设定插件版本的情况有以下几种:

1 核心插件:通过超级POM继承设定版本
2 非核心插件:通过仓库元数据 groupId/artifactId/maven-metadata.xml ,遍历并归并本地仓库和远程仓库的仓库元数据,根据latest和release计算出插件的版本。Maven3之后使用release,避免使用latest获取到快照版本,因为快照版本的频繁更新会导致插件行为的不稳定。

4)解析插件前缀

mvn命令行支持使用插件前缀来简化插件的调用。Maven是如何通过插件前缀获取插件的坐标的?
插件前缀与groupId:artifactId是一一对应的,这种匹配关系存储在仓库元数据中,该仓库员数据位于groupId/maven-metadate.xml,Maven在解析插件仓库元数据时,会默认使用org.apache.maven.plugins和org.codehaus.mojo两个groupId,可以再settings.xml中配置其他groupId

<settings>
    ...
    <pluginGroups>
        <pluginGroup>...</pluginGroup>
    </pluginGroups>
    ...
<settings>

插件仓库元数据中存储了所有插件前缀与group:artifactId的对应关系
插件仓库元数据检查顺序为:apache -> codehaus -> 用户自定义插件组 -> 都不包含该前缀,则报错

猜你喜欢

转载自blog.csdn.net/haoxin963/article/details/82828703