当项目中参考网上简单配置就可以打包跑起来的时候,很少会有人关注maven的基础知识,只是知道大致是干嘛的就行了,现实也的确是这样,我也觉得就应该是这样,当项目需要优化,一些诉求需要定制的时候就需要深入了解一些基础知识,不能盲目搜索参考不符合自己情况的案例瞎干,不然你只能堆时间去填补自己亲自埋的坑(别人的就更过分了)。本文就是有感而写,怕误人子弟,表达自己观点的同时也尽可能的贴上官方地址!
Fatjar 中的结构
maven 构建生命周期
生命周期
Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段
下图有插件执行阶段依赖的生命周期事件,一定要注意插件配置的<phase>
标签
<plugin>
<groupId>
<artifactId>
<version></version>
<executions>
<!--执行的内容-->
<execution>
<id></id>
<!-- 配置的执行的阶段标识了该任务执行的阶段, prepare-package打包前、package打包 等等等,不能是随意值-->
<phase>prepare-package</phase>
<goals>
<goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
重点关注的是default阶段:
默认生命周期包含以下阶段(有关生命周期阶段的完整列表,请参阅生命周期参考):
validate
- 验证项目是否正确并且所有必要的信息都可用compile
- 编译项目的源代码test
- 使用合适的单元测试框架测试编译的源代码。这些测试不应该要求打包或部署代码package
- 获取已编译的代码并将其打包成可分发的格式,例如 JAR。verify
- 对集成测试的结果进行任何检查,以确保满足质量标准install
- 将包安装到本地存储库中,作为本地其他项目的依赖项deploy
- 在构建环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享。
插件
Maven 本质上是一个插件执行框架;所有工作都由插件完成。同时 Maven 基于构建生命周期的核心概念,明确定义了构建和分发特定工件(项目)的过程。
构建插件(Build plugins): 将在构建期间执行,它们应该在 <build/>
POM 文件中配置
报告插件(Reporting plugins): 将在站点生成期间执行,它们应在<reporting/>
POM 文件中进行配置。
插件可选阶段值
<phases>
<phase>validate</phase>
<phase>initialize</phase>
<phase>generate-sources</phase>
<phase>process-sources</phase>
<phase>generate-resources</phase>
<phase>process-resources</phase>
<phase>compile</phase>
<phase>process-classes</phase>
<phase>generate-test-sources</phase>
<phase>process-test-sources</phase>
<phase>generate-test-resources</phase>
<phase>process-test-resources</phase>
<phase>test-compile</phase>
<phase>process-test-classes</phase>
<phase>test</phase>
<phase>prepare-package</phase>
<phase>package</phase>
<phase>pre-integration-test</phase>
<phase>integration-test</phase>
<phase>post-integration-test</phase>
<phase>verify</phase>
<phase>install</phase>
<phase>deploy</phase>
</phases>
maven 插件的基本知识
插件目标代表了一个特定的任务(比构建阶段更精细),它有助于项目的构建和管理。它可能绑定到零个或多个构建阶段。未绑定到任何构建阶段的目标可以通过直接调用在构建生命周期之外执行。执行顺序取决于调用目标和构建阶段的顺序。
其基本配置知识可以见官方网址:https://maven.apache.org/guides/mini/guide-configuring-plugins.html
简单总结主要的有如下几点:
- 所有插件都应具有最少的必需信息:
groupId
,artifactId
和version
- 保证构建可重复性。一个好的做法是在一个
<build><pluginManagement/></build>
元素中指定每个构建插件的版本pluginManagement一般是用来在父POM中定义,提供给子POM使用,子POM也可以覆盖这个定义,而且你在父POM中定义了版本之后,子模块中直接应用groupId和artifactId,而不用指定版本,同时也方便统一管理;而在父POM中的pluginManagement并不会介入到Maven的生命周期
示例
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<executions>
maven 插件的命名约定
有着自己的一套命名规范。官方插件命名的格式为 [maven-xxx
-plugin],非官方的插件命名为 [xxx
-maven-plugin] 。是不是觉得很眼熟,没错,spring boot starter 的命名也有类似的规范。
如下几个插件可以看其名字就能区分是maven官方的还是非官方的:spring-boot-maven-plugin、maven-surefire-plugin、maven-resources-plugin
官方插件可以详见官方地址:https://maven.apache.org/plugins/index.html
打包瘦身
网上说使用 spring-boot-maven-plugin
打包会有问题,目前我尝试没有问题,springboot框架提供了一套自己的打包机制,而且使用 spring boot官方的插件更简单,详细情况请参见另一篇文章:基于spring-boot-maven-plugin插件打包lib文件外置,layout模式为ZIP模式