配置插件指南
介绍
在 Maven 中,有两种插件,构建和报告:
- 构建插件在构建期间执行并在
<build/>
元素中配置。 - 报告插件在站点生成期间执行并在
<reporting/>
元素中配置。
所有插件都应具有最少的必需信息:groupId
,artifactId
和version
。
重要提示:始终定义每个插件的版本,以保证构建可重复性。一个好的做法是在一个<build><pluginManagement/></build>
元素中指定每个构建插件的版本。<pluginManagement/> 元素通常可以在父 POM 中找到。对于报告插件,请在元素中指定每个版本<reporting><plugins/></reporting>
(以及在<build><pluginManagement/></build>
元素中)。
通用配置
Maven 插件(构建和报告)通过指定一个<configuration>
元素来配置,其中该元素的子元素<configuration>
映射到 Mojo 中的字段或设置器。(请记住,插件由一个或多个 Mojo 组成,其中 Mojo 映射到一个目标。)例如,您有一个 Mojo,它针对特定 URL 执行查询,具有指定的超时和选项列表。Mojo 可能如下所示:
/** * @goal query */ public class MyQueryMojo extends AbstractMojo { @Parameter(property = "query.url", required = true) private String url; @Parameter(property = "timeout", required = false, defaultValue = "50") private int timeout; @Parameter(property = "options") private String[] options; public void execute() throws MojoExecutionException { ... } }
要使用所需的 URL、超时和选项从您的 POM 配置 Mojo,您可能需要以下内容:
<project> ... <build> <plugins> <plugin> <artifactId>maven-myquery-plugin</artifactId> <version>1.0</version> <configuration> <url>http://www.foobar.com/query</url> <timeout>10</timeout> <options> <option>one</option> <option>two</option> <option>three</option> </options> </configuration> </plugin> </plugins> </build> ... </project>
配置中的元素与 Mojo 中的字段名称相匹配。映射是直截了当的。url
元素映射到url
字段,元素timeout
映射到timeout
字段,options
元素映射到options
字段。映射机制可以通过检查字段的类型并确定是否可以进行合适的映射来处理数组。
对于打算直接从 CLI 执行的 Mojo,它们的参数通常提供一种通过系统属性而不是<configuration>
POM 中的部分进行配置的方法。这些参数的插件文档将列出一个表示配置的系统属性的表达式。在上面的 Mojo 中,参数url
与表达式 相关联${query.url}
,这意味着它的值可以由系统属性指定,query.url
如下所示:
mvn myquery:query -Dquery.url=http://maven.apache.org
系统属性的名称不一定与 mojo 参数的名称匹配。虽然这是一种相当常见的做法,但您经常会注意到插件为系统属性使用了一些前缀,以避免与其他系统属性发生名称冲突。虽然很少见,但也有一些插件参数(例如出于历史原因)使用与参数名称完全无关的系统属性。因此,请务必仔细查看插件文档。
帮助目标
大多数 Maven 插件都有一个help
目标,即打印插件及其参数和类型的描述。例如,要查看 javadoc 目标的帮助,请键入:
mvn javadoc:help -Ddetail -Dgoal=javadoc
您将看到 javadoc:javadoc 目标的所有参数,类似于此页面。
配置参数
映射简单对象
映射简单类型,如 Boolean 或 Integer,非常简单。该<configuration>
元素可能如下所示:
... <configuration> <myString>a string</myString> <myBoolean>true</myBoolean> <myInteger>10</myInteger> <myDouble>1.0</myDouble> <myFile>c:\temp</myFile> <myURL>http://maven.apache.org</myURL> </configuration> ...
映射复杂对象
映射复杂类型也相当简单。让我们看一个简单的例子,我们试图为 Person 对象映射一个配置。该<configuration/>
元素可能如下所示:
... <configuration> <person> <firstName>Jason</firstName> <lastName>van Zyl</lastName> </person> </configuration> ...
映射复杂对象的规则如下:
- 必须有一个对应于被映射元素名称的私有字段。所以在我们的例子中,
person
元素必须映射到person
mojo 中的一个字段。 - 实例化的对象必须与 Mojo 本身在同一个包中。因此,如果您的 mojo 在其中,
com.mycompany.mojo.query
则映射机制将在该包中查找名为Person
. 该机制将元素名称的第一个字母大写,并使用它来搜索要实例化的对象。 - 如果您希望将要在不同包中实例化的对象或具有更复杂的名称,请使用如下
implementation
属性指定:
... <configuration> <person implementation="com.mycompany.mojo.query.SuperPerson"> <firstName>Jason</firstName> <lastName>van Zyl</lastName> </person> </configuration> ...
映射集合
配置映射机制可以轻松处理大多数集合,因此让我们通过几个示例向您展示它是如何完成的:
映射列表
映射列表的工作方式与映射到数组的方式大致相同,其中元素列表将映射到列表。因此,如果您有如下的魔力:
public class MyAnimalMojo extends AbstractMojo { @Parameter(property = "animals") private List animals; public void execute() throws MojoExecutionException { ... } }
如果您有一个名为的字段animals
,那么您的插件配置将如下所示:
<project> ... <build> <plugins> <plugin> <artifactId>maven-myanimal-plugin</artifactId> <version>1.0</version> <configuration> <animals> <animal>cat</animal> <animal>dog</animal> <animal>aardvark</animal> </animals> </configuration> </plugin> </plugins> </build> ... </project>
列出的每个动物都是该animals
字段中的条目。与数组不同,集合没有特定的组件类型。为了导出列表项的类型,使用以下策略:
- 如果 XML 元素包含
implementation
提示属性,则使用 - 如果 XML 标记包含 a
.
,请尝试将其作为完全限定的类名 - 尝试将 XML 标记(首字母大写)作为与正在配置的 mojo/object 相同的包中的类
- 如果元素没有子元素,则假定其类型为
String
。否则,配置将失败。
映射地图
同样,您可以定义如下映射:
... @Parameter(property = "myMap") private Map myMap; ...
... <configuration> <myMap> <key1>value1</key1> <key2>value2</key2> </myMap> </configuration> ...
映射属性
属性应定义如下:
... @Parameter(property = "myProperties") private Properties myProperties; ...
... <configuration> <myProperties> <property> <name>propertyName1</name> <value>propertyValue1</value> </property> <property> <name>propertyName2</name> <value>propertyValue2</value> </property> </myProperties> </configuration> ...
配置构建插件
以下只是在<build>
元素中配置构建插件。
使用<executions>
标签
您还可以使用<executions>
标签配置 mojo。这最常用于旨在参与构建生命周期某些阶段的 mojo 。举MyQueryMojo
个例子,你可能有一些看起来像:
<project> ... <build> <plugins> <plugin> <artifactId>maven-myquery-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>execution1</id> <phase>test</phase> <configuration> <url>http://www.foo.com/query</url> <timeout>10</timeout> <options> <option>one</option> <option>two</option> <option>three</option> </options> </configuration> <goals> <goal>query</goal> </goals> </execution> <execution> <id>execution2</id> <configuration> <url>http://www.bar.com/query</url> <timeout>15</timeout> <options> <option>four</option> <option>five</option> <option>six</option> </options> </configuration> <goals> <goal>query</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </project>
id 为“execution1”的第一次执行将此配置绑定到测试阶段。第二次执行没有<phase>
标签,你认为这次执行会表现如何?好吧,目标可以有一个默认的阶段绑定,如下面进一步讨论的。如果目标具有默认阶段绑定,那么它将在该阶段执行。但是如果目标没有绑定到任何生命周期阶段,那么它就不会在构建生命周期中执行。
请注意,虽然执行 id 在 POM 中单个插件的所有执行中必须是唯一的,但它们在 POM 的继承层次结构中不必是唯一的。来自不同 POM 的相同 id 的执行被合并。这同样适用于配置文件定义的执行。
如果我们有绑定到不同阶段的多个执行呢?你认为它会如何表现?让我们再次使用上面的示例 POM,但这次我们将绑定execution2
到一个阶段。
<project> ... <build> <plugins> <plugin> ... <executions> <execution> <id>execution1</id> <phase>test</phase> ... </execution> <execution> <id>execution2</id> <phase>install</phase> <configuration> <url>http://www.bar.com/query</url> <timeout>15</timeout> <options> <option>four</option> <option>five</option> <option>six</option> </options> </configuration> <goals> <goal>query</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </project>
如果有多个执行绑定到不同的阶段,那么 mojo 会为每个指示的阶段执行一次。意思是,execution1
将在构建阶段为测试时execution2
应用配置设置执行,并在构建阶段已安装时应用配置设置执行。
现在,让我们来看看另一个 mojo 示例,它显示了默认的生命周期阶段绑定。
/** * @goal query * @phase package */ public class MyBoundQueryMojo extends AbstractMojo { @Parameter(property = "query.url", required = true) private String url; @Parameter(property = "timeout", required = false, defaultValue = "50") private int timeout; @Parameter(property = "options") private String[] options; public void execute() throws MojoExecutionException { ... } }
从上面的 mojo 示例MyBoundQueryMojo
中,默认绑定到包阶段(参见@phase
符号)。<phase>
但是,如果我们想在安装阶段而不是包中执行这个 mojo,我们可以使用<execution>
.
<project> ... <build> <plugins> <plugin> <artifactId>maven-myquery-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>execution1</id> <phase>install</phase> <configuration> <url>http://www.bar.com/query</url> <timeout>15</timeout> <options> <option>four</option> <option>five</option> <option>six</option> </options> </configuration> <goals> <goal>query</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </project>
现在,MyBoundQueryMojo
作为包的默认阶段已被安装阶段覆盖。
注意:元素内部的配置<executions>
与外部的配置不同,<executions>
因为它们不能从直接命令行调用中使用,因为它们仅在调用它们绑定到的生命周期阶段时应用。因此,您必须将配置部分移到执行部分之外,以将其全局应用于插件的所有调用。由于 Maven 3.3.1 不再是这种情况,因为您可以在命令行上指定直接插件目标调用的执行 ID。因此,如果您想从命令行运行上述插件并且它是特定的 execution1 配置,您可以执行:
mvn myqyeryplugin:queryMojo@execution1
使用<dependencies>
标签
您可以配置构建插件的依赖项,通常使用更新的依赖项版本。
例如 Maven Antrun Plugin 1.2 版使用 Ant 1.6.5 版,如果你想在运行这个插件时使用最新的 Ant 版本,你需要添加<dependencies>
如下元素:
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.2</version> ... <dependencies> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant-launcher</artifactId> <version>1.7.1</version> </dependency> </dependencies> </plugin> </plugins> </build> ... </project>
在构建插件中使用<inherited>
标签
默认情况下,插件配置应该传播到子 POM,所以要打破继承,你可以使用<inherited>
标签:
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.2</version> <inherited>false</inherited> ... </plugin> </plugins> </build> ... </project>
配置报告插件
以下仅用于在<reporting>
元素中配置报告插件。
使用<reporting>
标签 VS<build>
标签
在 pom 中的 <reporting> 或 <build> 元素中配置报告插件没有相同的行为!
mvn site
- 它仅使用<reporting> 元素中指定的每个报告插件的 <configuration> 元素中定义的参数,即
site
始终忽略<build> 中指定的每个插件的 <configuration> 元素中定义的参数。 mvn aplugin:areportgoal
- 它首先使用在 <reporting> 元素中指定的每个报告插件的 <configuration> 元素中定义的参数;如果找不到参数,它将查找在 <build> 中指定的每个插件的 <configuration> 元素中定义的参数。
使用<reportSets>
标签
<reportSets>
您可以使用标签配置报告插件。这最常用于在运行时选择性地生成报告mvn site
。以下将仅生成项目团队报告。
<project> ... <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.1.2</version> <reportSets> <reportSet> <reports> <report>project-team</report> </reports> </reportSet> </reportSets> </plugin> </plugins> </reporting> ... </project>
备注:
- 要排除所有报告,您需要使用:
<reportSets> <reportSet> <reports/> </reportSet> </reportSets>
- 请参阅每个插件文档(即 plugin-info.html)以了解可用的报告目标。
<inherited>
在报告插件中使用标签
与构建插件类似,要打破继承,可以使用<inherited>
标签:
<project> ... <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.1.2</version> <inherited>false</inherited> </plugin> </plugins> </reporting> ... </project>