简介
Maven 和 gradle 应该是现代 java 程序员中使用的最多的两种构建工具。在它们出现之前,则是 ant 的天下。
Maven 为我们封装了很多构建中非常有用的操作,我们只需要执行简单的几个 mvn 命令即可。
今天我们要讨论一下 mvn 命令之下的生命周期的构建。
更多精彩内容且看:
- 区块链从入门到放弃系列教程 - 涵盖密码学, 超级账本, 以太坊,Libra, 比特币等持续更新
- Spring Boot 2.X 系列教程: 七天从无到有掌握 Spring Boot- 持续更新
- Spring 5.X 系列教程: 满足你对 Spring5 的一切想象 - 持续更新
- java 程序员从小工到专家成神之路(2020 版)- 持续更新中, 附详细文章教程
更多内容请访问 www.flydean.com
lifecycle 和 Phases
所谓 lifecycle,可以理解为可以执行一组命令的集合,用来执行具体的某些操作。
Maven 默认有三种 lifecycle:default,clean 和 site。default 主要用来处理项目的开发,clean 主要用来负责项目的清理,site 主要用来生成项目的文档。
lifecycle 是由一个或者多个 phase 组成的。
以 default 为例,它大概由 23 个 phases 组成,这些 phases 将会按顺序执行来完成 default 的 lifecycle。
我们选取 default lifecycle 中非常常见的几个 phase 来说明一下:
- validate – 用来验证项目是否正确或者项目所需要的信息是否可用。
- compile – 用来编译项目代码
- test – 执行代码中的单元测试
- package – 将编译后的代码进行打包,打包可有很多种方式,比如:jar,war 等
- verify – 执行集成测试
- install – 将项目安装到本地仓库中,供有依赖关系的其他项目使用
- deploy – 将项目部署到远程仓库,以便共享给其他的用户
上面的 phase 执行是有顺序的,比如我们如果执行 mvn verify,则会顺序执行 validate,compile,test 和 package。
Phases 和 Goals
Phases 是一种任务的集合,它是由一个或者多个 Goals 组成的。Goals 可以包含在 Phases 里面执行,也可以单独用命令执行。
那么 Goals 又是从哪里来的呢?Goals 是定义在 maven 中的 plugin 中的。
我们看下面一张直观的图:
下图列出了现有 lifecycle 中的 phase,和相应 phase 所对应的 plugin。
我们可以看到基本每个 phase 都和一个 plugin 中的 golas 是相对于应的。
除了使用命名直接指定要执行的 phase 以外,还可以直接指定 goals:
mvn clean dependency:copy-dependencies package
上面的命令中 clean 和 package 是 phase,而 copy-dependencies 则是 goals。
常用 plugin 介绍
这里我们介绍两个非常常用的 maven plugin,maven-dependency-plugin 和 maven-jar-plugin。
maven-dependency-plugin
maven 中的依赖 jar 包是存放在 maven 的本地仓库中的,如果项目中依赖了某些 jar 包,在部署的时候还需要这些依赖的 jar 包拷贝出来,非常不方便,有了 maven-dependency-plugin,则可以借用它的 copy-dependencies 来将项目的依赖 jar 包拷贝出啦,如下所示:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
goals 是和相应的 phase 相关联的,在上面的例子中,我们将 copy-dependencies 和 package 相关联,则在我们执行 mvn package 的时候就会自动执行 copy-dependencies,从配置文件可以知道,我们将会把项目的依赖 jar 包拷贝到项目的 build 目录的 lib 目录下。
maven-jar-plugin
有了依赖的 lib,可以将 main 程序打包成为一个可执行的 jar 包。这时候我们就需要使用到 maven-jar-plugin。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.flydean.MavenClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
为了生成可执行的 jar 包,我们需要在 MANIFEST.MF 文件中添加 mainClass 文件的路径,这样在执行 jar 包的时候,无需额外的参数即可运行。
遗憾的是,如果我们的 class 文件用到了外部 jar 包的依赖时候,jar 包直接运行会出错,因为找不到所依赖的 jar 包。
在介绍 maven-dependency-plugin 的时候,我们已经把所用到的 lib 拷贝出来了,这里我们可以直接使用:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.flydean.MavenClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
多加了两个 addClasspath 的参数,我们将打包好的 jar 包解压缩。
可以看到里面多了一个 MANIFEST.MF 的文件:
Manifest-Version: 1.0
Created-By: Maven Jar Plugin 3.2.0
Build-Jdk-Spec: 14
Class-Path: lib/lombok-1.18.10.jar lib/logback-classic-1.2.3.jar lib/log
back-core-1.2.3.jar lib/slf4j-api-1.7.25.jar
Main-Class: com.flydean.MavenClass
这个文件里面包含了一些 jar 包的元数据,并且里面添加了 Class-Path 和 Main-Class 文件,这时候执行运行 jar 包就可以直接执行了。
总结
本文介绍了 maven 构建时候的生命周期,并介绍了两个经常会使用到的 plugin。
本文的例子 [https://github.com/ddean2009/
learn-java-base-9-to-20](https://github.com/ddean2009/…
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/apache-maven-lifecycle/
本文来源:flydean 的博客
欢迎关注我的公众号: 程序那些事,更多精彩等着您!