1. 前言
Maven is - at its heart - a plugin execution framework; all work is done by plugins.
maven实际上一个插件执行框架,所有的工作实际上都是通过插件完成,一个插件通常提供若干目标(goal),通过如下形式的命令执行插件目标:
mvn [plugin name]:[goal name]
例如可以通过编译插件compiler去编译目标,命令如下:
mvn compiler:compile
插件类型
插件有两类:
插件类型 | 解释 |
---|---|
build plugins | build项目时期执行这类插件,且这类插件必须配置在pom的<build></build>中 |
report plugins | mvn site期间执行的插件,用于生成项目报表文档之类的,需要配置在pom的<reporting></reporting>之间 |
由于我从来没有用过report plugin,所以本文只会讲build plugins。
2. 生命周期
maven是一种基于构建生命周期(build lifecycle)的项目构建工具, 也就是说一个项目的构建和发布是要经历几个过程的,目前主要包含三个过程:
- clean
- default
- site
这其中每一个过程又有若干个阶段(phase)组成。下面列表只是简单列出了开发者比较常见的phase:
1. clean
phase | 解释 |
---|---|
clean | 起初之前一起build生成的文件 |
2. default
phase | 解释 |
---|---|
validate | 对项目的必要信息或资源进行验证 |
initialize | 初始化操作,比如常见目录,设置属性 |
compile | 编译源文件 |
test | 使用测试框架跑所有测试用例 |
package | 打包项目 |
install | 部署到本地repository |
deploy | 发布到远程仓库 |
phase | 解释 |
---|---|
site | 生成项目文档的网页资源 |
3. site
phase | 解释 |
---|---|
site | 生成项目文档的网页资源 |
使用过mvn的就会发现,一个phase对应一个mvn的命令,比如当执行mvn compile
命令时就是执行该phase之前的所有phase。
但是前言中说过mvn是通过插件来执行任务的,当执行mvn compile
这个phase时,实际上是执行绑定在compile这个phase上的插件目标,由于compile这个phase默认绑定了compiler: compile
(compiler插件的compile目标),因此执行mvn compile
等于去执行了mvn compiler:compile
再例如:执行mvn package
实际上执行了插件mvn jar:jar
(注意此处假设pom里配置了<packaging>jar<package>), 因为package这个phase默认绑定了jar:jar
这个插件目标。
附:
这一节只是简单介绍了插件构建的生命周期一个,省略了一些内容,更多的细节请参考官方文档介绍mvn 生命周期
3. 插件配置
本文只介绍build plugin, build plugin需要写在pom文件的<build></build>
中,
一个插件通常包含如下配置:
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
</build>
</project>
- 一个<plugin></plugin>表示一个插件, <groupId>,<artifactId>,<version>都是引入必要配置。插件本质上托管在mvn仓库里。
- <inherited>表示是否当前pom的子pom中继承这个插件配置,true表示子pom继承父pom这个插件配置,那么你就可以在子pom上通过mvn命令使用这个插件
- <configuration>中包含了插件类实例化时用于初始化类成员信息
- <dependencies>, 插件自身也会依赖外部包,<dependencies>中可以为插件指定特定的依赖包, 引入方式如下:
<dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> </dependency> </dependencies>
- <executions>, 一个插件可能包含多个goal,<executions>中可以单独为某个goal指定配置,以及将goal绑定到某个phase。executions包含的elements如下:
<executions> <execution> <!--需要在<executions>里面唯一的id--> <id></id> <!--列出需要特定去配置的所有goal--> <goals> <goal>run</goal> </goals> <!--将这些goal绑定到phase--> <phase>verify</phase> <!--指定子pom是否继承这些配置--> <inherited>false</inherited> <configuration> <!--这里指定配置--> </configuration> </execution> <execution> ... </execution> ... </executions>
一个示例
比如下面就是一个几乎所有人都会用到的插件配置,compiler:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version> <!--指定compiler插件版本信息-->
<configuration>
<!--插件实例化参数,这个参数是设置javac -source的值-->
<source>1.7</source>
<!--插件实例化参数,这个参数是设置javac -target的值-->
<target>1.7</target>
</configuration>
</plugin>
这里没有指定<executions>,因为compiler插件的目标compile默认被绑定到compile这个phase上了,
目标testCompile被绑定到了test-compile这个phase上了。
当然你可以显式指定,加入如下配置即可:
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>compile</phase>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
所以当执行mvn compile
时其实执行了插件目标mvn compiler:compile
,执行mvn test-compile
时执行了插件目标mvn compiler:testCompile
.
附
- 关于插件参数配置参考guide-configuring-plugins
- 关于pom中使用插件参考plugins in pom
- 关于maven插件列表参考available plugins