Maven实战03-生命周期和插件
Maven实战03-生命周期和插件
maven的核心概念:坐标、依赖(这两个上一节说了)、仓库(先看知乎上那里暂时足够了,等到我自己创个私服以后再深入仓库概念)、生命周期、插件(本文详解)
maven出现之前,对于一个项目来说至少包括了清理、编译、测试和部署。公司间差异较大,有些以手工方式,有一些则以自动化脚本进行。
maven的生命周期
maven从大量项目和构建工具中学习总结了自己的一套生命周期。具体包括了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点。当然,maven包含那么多生命周期,其实我们并不一定都用得到。
maven的生命周期并不是一个整体,maven拥有三套相互独立的生命周期,它们分别是clean、default和site。clean的目的是清理项目、default目的是构建项目,site生命周期的目的是建立项目站点。
三个生命周期独立的意思是你可以仅仅调用clean生命周期而不会影响到default生命周期,但是在一个生命周期中每个阶段是有顺序的,后一个依赖于前一个的执行。我们使用maven实际上就是有目的地调用这些生命周期
clean生命周期
清理项目,包含三个阶段
- pre-clean:执行一些清理前需要完成的工作
- clean:清理上一次构建生成的文件
- post-clean:执行一些清理后需要完成的工作
default生命周期
真正构建时所需要执行的所有步骤,所有生命周期中最核心的部分,包含的阶段如下,重要阶段会加粗。其他阶段你甚至可以不看,不要被那么多字吓到,我只是在后面把原文的英文加上去了而已。
- validate:验证项目是否正确并且所有必要的信息都可用。(validate the project is correct and all necessary information is available.)
- initialize:初始化构建状态,例如设置属性或创建目录。(initialize build state, e.g. set properties or create directories.)
- generate-sources:生成任何源代码以包含在编译中。(generate any source code for inclusion in compilation.)
- process-sources:处理项目主资源文件。一般来说,是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中。(process the source code, for example to filter any values.)
- generate-resources:生成包含在包中的资源。(generate resources for inclusion in the package.)
- process-resources:将资源复制并处理到目标目录中,准备打包。(copy and process the resources into the destination directory, ready for packaging.)
- compile:编译项目的主源码。一般来说,是编译src/main/java目录下的Java文件至项目输出的主classpath目录中。(compile the source code of the project.)
- process-classes:对编译生成的文件进行后处理,例如对 Java 类进行字节码增强。(post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.)
- generate-test-sources:生成任何测试源代码以包含在编译中。(generate any test source code for inclusion in compilation.)
- process-test-sources:处理项目测试资源文件。一般来说,是对/src/test/resources目录的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中。(process the test source code, for example to filter any values.)
- generate-test-resources:为测试创建资源。(create resources for testing.)
- process-test-resources:将资源复制并处理到测试目标目录中。(copy and process the resources into the test destination directory.)
- test-compile:编译项目的测试代码。一般来说,是编译src/test/java目录下的Java文件至项目输出的测试classpath目录中(compile the test source code into the test destination directory)
- process-test-classes:对测试编译生成的文件进行后处理,例如对 Java 类进行字节码增强。(post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes.)
- test:使用单元测试框架运行测试,测试代码不会被打包或部署。(run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.)
- prepart-package:在实际包装之前执行准备包装所需的任何操作。这通常会导致包的解包、处理版本。(perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package.)
- package:接受编译好的代码,打包成可发布的格式,如JAR。(take the compiled code and package it in its distributable format, such as a JAR.)
- pre-integration-test:在执行集成测试之前执行所需的操作。这可能涉及诸如设置所需环境之类的事情。(perform actions required before integration tests are executed. This may involve things such as setting up the required environment.)
- integration-test:处理并在必要时将包部署到可以运行集成测试的环境中。( process and deploy the package if necessary into an environment where integration tests can be run.)
- post-integration-test:执行集成测试后执行所需的操作。这可能包括清理环境。(perform actions required after integration tests have been executed. This may including cleaning up the environment.)
- verify:运行任何检查以验证包是否有效并符合质量标准。(run any checks to verify the package is valid and meets quality criteria.)
- install:将包安装到maven本地仓库,供本地其他maven项目使用。(install the package into the local repository, for use as a dependency in other projects locally.)
- deploy:将最终的包复制到远程仓库,供其他开发人员和maven项目使用。(done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
site生命周期
目的是建立和发布项目站点,maven能基于pom所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段。
- pre-site:执行一些在生成项目站点之前需要完成的工作。
- site:生成项目站点文档。
- post-site:执行一些在生成项目站点之后需要完成的工作。
- site-deploy:将生成的项目站点发布到服务器上。
命令行的意义
从命令行执行maven任务就是调用maven的生命周期。
mvn clean
:调用clean生命周期的clean阶段,实际执行的阶段为clean生命周期的pre-clean和cleanmvn test
调用default生命周期的test阶段。实际执行的阶段为default生命周期test及其之前的。这也解释了为什么在执行测试的时候,项目的代码能够编译。mvn clean install
:同理调用了clean生命周期所有阶段和default生命周期的install阶段及其之前阶段。结合两个生命周期,执行真正的项目构建之前清理项目是一个很好的实践。mvn clean deploy site-deploy
:该命令结合了maven所有三个生命周期,三个都是所处生命周期的最后一个阶段。
Maven插件
maven的生命周期是与插件相互绑定的,用来完成具体的构建任务。你显式地执行maven的生命周期,实际上是在运行绑定了这个生命周期的插件来实现操作的。当然一个插件可以绑定多个生命周期。像是clean生命周期就只与一个插件maven-clean-plugin:clean
绑定。
总之你暂时可以理解为插件是maven生命周期的具体实现。
默认绑定
default生命周期当然还有很多其他阶段,默认它们没有绑定任何插件,因此也没有任何实际行为。
1 |
|
上述代码是对我demo项目执行mvn clean install
命令所产生的输出,其中maven-clean-plugin:2.5:clean (default-clean)
不正是代表了对应插件,对应生命周期的说法么。
自定义绑定
除了内置绑定,用户还可以自己选择将某个插件目标绑定到生命周期的某个阶段上。一个非常常见的例子就是创建项目的源码jar包还有把第一篇文章中的需要借助插件生成可执行的jar。
1 |
|
上面代码是之前的复制,你可以看到<execution>
标签下面的<phase>
其中就是指定需要在哪个生命周期执行该插件。
具体的解释是<executions>
标签下的每一个<execution>
都可以用来配置执行一个任务。任务可以绑定生命周期,然后当你执行具体的生命周期时,自然可以看到对应插件信息的日志打印。
插件配置
了解了插件和生命周期的绑定,我们还需要了解如何配置插件目标的参数,来进一步调整插件所执行的任务。
命令行插件配置
很多插件都支持从命令行配置,用户可以在maven命令中使用-D
参数,并伴随一个参数键=参数值的形式,来配置插件目标的参数。
例如:maven-surefire-plugin提供了一个maven.test.skip参数,当值为true时,就会跳过执行测试。
于是运行命令时使用 mvn install -D maven.test.skip=true
就能跳过测试。
POM中插件全局配置
并不是所有插件都适合从命令行配置,有些参数很少改变。那么对于这种情况,在POM文件中一次性配置就比重复在命令行输入更方便。
1 |
|
例如对这个插件来说,你在<configuration>
标签中配置的就是全局配置。告诉它编译Java1.8的源文件,生成与JVM1.8兼容的字节码文件。
POM中插件任务配置
除了配置插件全局配置,还可以配置单独任务的配置,这里在上面自定义配置中你就可以看到是通过在<execution>
标签下<configuration>
标签中配置的。当然这个标签里面的字段并没有介绍完,比如还有<id>
标签。不过嘛了解怎么配置也就足够了。其他标签用到的时候单独查看即可。
调用插件
获取maven插件
在现在上网找资源应该很容易,百度搜索maven插件应该就会出现很多可以下载插件的网站。除了访问在线的插件文档之外,还可以借助maven-help-plugin
来获取插件的详细信息。比如你可以通过运行**mvn help:describe -Dplugin=org.springframework.boot:spring-boot-maven-plugin:2.1.6.RELEASE -Ddetail**
来获取spring-boot-maven-plugin的详细描述。在这个命令中你需要提供描述插件的groupId和artifactId。
从命令行调用插件
有一些插件时不需要绑定生命周期的,就比如mvn help
它仅仅是描述信息,绑定在某一个生命周期上也不合适。查看下面两个插件命令行
1 |
|
其实完整版本是下面这个
1 |
|
他们的效果是一样,至少在我的电脑假如版本最新就是2.1和3.2.0的话。但是如果命令行都使用下面的写法未免也太繁琐了。所以maven引入了目标前缀的概念,help是maven-help-plugin的目标前缀,dependency是maven-dependency-plugin的目标前缀。
插件解析机制
与依赖构建一样,插件也一样需要groupid和artifactId。不同于仓库可以下载快照版的依赖,对于插件来说默认插件仓库的地址关闭了对SNAPSHOT(快照版本)的支持。
上面的配置是所有maven项目都会集成的超级POM,这是用户不能修改的,嵌入程序里面的。当然如果你硬要改也是可以改的。一般来说不要改,中央仓库所包含的插件完全能够满足我们的需要,因此也不需要配置其他的插件仓库。如果插件时Maven的官方插件,即groupId为org.apache.maven.plugins就可以省略groupId的配置,不过还是建议写出来,这样可读性高一些。
那么插件时如何选择版本的呢?答案是在maven3中,官方插件都在超级POM中规定了版本,假如是其他插件,则会去找最新的稳定版本。
那么插件如何使用插件前缀来简化插件的调用呢?答案是插件前缀和groupId:artifactId的对应关系存储在仓库元数据中。如果org/apache/maven/plugins/maven-metadata.xml没有记录该插件,则接着检查其他groupId下的元数据,如org/codehaus/mojo/maven-metadata.xml,以及用户自定义的插件组。如果所有元数据都不包含该前缀,则报错
终于写完了,这一章对于理解maven来说至关重要,maven生命周期非常重要。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!