post:增加Maven POM文章。

This commit is contained in:
徐涛 2021-06-09 07:23:16 +08:00
parent c58acf4f09
commit 0dcb919dbc

View File

@ -0,0 +1,518 @@
---
title: Maven POM文件编辑技巧要点
tags:
- JVM
- Java
- Maven
- POM
categories:
- - JVM
- 构建工具
keywords: 'Maven,pom,pom.xml,构建,dependency'
date: 2021-06-09 07:22:33
---
Maven作为一个老牌的项目构建工具虽然在构建速度上不及Gradle的多线程构建快但是使用XML文件作为构建配置还是拥有不少好处的起码在进行配置的时候不会像Gradle一样自由的感觉无从下手。<!-- more -->
项目对象模型POM是Maven管理项目的基本工作单元一般采用XML编写其中包含了项目基本信息、构建信息以及依赖信息等。在Maven执行任务时会在当前目录中寻找POM并从中读取所需的配置信息然后执行相关任务。POM一般在目录中以`pom.xml`文件的形式存在。每个POM文件中都至少需要`project`根元素和`groupId`、`artifactId`、`verion`这三个必需元素。
Super POM是Maven的默认POM被所有的POM继承。Super POM可以通过命令`mvn help:effective-pom`查看。
## Maven构建生命周期
所有常用Maven命令实际上调用的都是Maven的各个生命周期动作也就是命令行格式`mvn [options] [goals] [phases]`中的`[phase]`。
在Maven中有三个标准生命周期`clean`、`default`、`site`,每个生命周期都包含一定的阶段(`phase`)。
### Clean生命周期
Clean周期主要执行项目的清理工作会移除上一次构建生成的所有文件。Clean周期包含以下几个阶段。
1. `pre-clean`,执行一些清理构建文件之前需要完成的操作。
1. `clean`,执行移除构建文件的操作。
1. `post-clean`,在移除构建文件之后需要完成的操作。
当执行命令`mvn post-clean`时,位于`post-clean`阶段之前的`pre-clean`和`clean`阶段都会按照预定顺序执行。这种阶段的执行模式对于其他声明周期也同样起效。
### Site生命周期
Site周期主要用来创建报告文档、部署站点等。主要包含四个阶段
1. `pre-site`,在生成站点之前需要完成的操作。
1. `site`,生成站点的文档。
1. `post-site`,在生成站点之后需要完成的工作,并且为部署做准备。
1. `site-deploy`,将生成的站点文档部署到特定的服务器上。
### Default生命周期
Default周期主要用于构建应用也称为Build周期是三个标准周期中最复杂的一个有23个阶段。
1. `validate`,校验项目是否正确并且已经具备的信息是否可以完成项目构建。
1. `initialize`,初始化构建状态。
1. `generate-sources`,生成包含在编译阶段中的全部源代码。
1. `process-sources`,处理生成的源代码。
1. `generate-resources`,生成将会包含在项目包中的资源文件。
1. `process-resources`,复制和处理资源到目标目录。
1. `compile`,编译全部源代码。
1. `process-classes`,处理编译生成的文件,进行优化。
1. `generate-test-sources`,生成包含在编译阶段中的全部测试源代码。
1. `process-test-sources`,处理生成的测试源代码。
1. `generate-test-resources`,为测试创建资源文件。
1. `process-test-resources`,复制和处理测试资源到目标目录。
1. `test-compile`,编译全部测试源代码。
1. `process-test-classes`,处理和测试源码编译生成的文件。
1. `test`,运行单元测试。
1. `prepare-package`,在打包之前,执行全部必要操作。
1. `package`,将编译后的代码打包为可分发格式文件。
1. `pre-integration-test`,执行集成测试之前所必要的操作。
1. `integration-test`,部署项目到集成测试环境中。
1. `post-integration-test`,执行完集成测试之后进行的必要操作。
1. `verify`,运行指定的检查来确定项目包有效且达到指定质量标准。
1. `install`,将项目包安装到本地仓库,使其可以作为其他项目的依赖。
1. `deploy`,将项目包部署到远程仓库使其可以与其他开发者共享。
## POM文件结构
POM文件在编辑的时候可以依照以下标签解释内容来完成编辑。
{% codeblock lang:xml wrap:true %}
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="httpL//www.w3.org/2001/XMLScema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!--父项目坐标,包括 groupId、artifactId和version-->
<parent>
<!--被继承的父项目全球唯一标识-->
<groupId></groupId>
<!--被继承的父项目的构件标识-->
<artifactId></artifactId>
<!--被继承的父项目版本-->
<version></version>
<!--父项目的 pom.xml 文件的相对路径,默认是 ../pom.xml。Maven 会按照此处定义的路径、本地仓库、远程仓库的顺序寻找父项目 POM-->
<relativePath></relativePath>
</parent>
<!--声明项目描述所遵循的 POM 模型版本-->
<modelVersion>4.0.0</modelVersion>
<!--groupId、artifactId 和 version 被合称为 GAV是可以用来定位项目的坐标-->
<!--项目全球唯一标识,通常使用全限定的包名来区分,并且影响构建时的路径-->
<groupId>com.example</groupId>
<!--构件的标识,与 groupId 搭配标识一个构件-->
<artifactId>app</artifactId>
<!--项目当前的版本,通常采用 主版本.次版本.增量版本-限定版本 的格式-->
<version>1.0.0-SNAPSHOT</version>
<!--项目产生的构件类型常用的例如jar、war、pom 等-->
<packaging>jar</packaging>
<!--建立文档时所要使用的项目名称-->
<name>Application</name>
<!--项目主页URL建立文档时使用-->
<url></url>
<!--项目详细描述可以包含HTML标签但不能使用 CDATA 文本。-->
<description></description>
<!--描述构件环境前提条件-->
<prerequisites>
<!--构建该项目所需要使用的 Maven 最低版本-->
<maven />
</prerequisites>
<!--项目问题管理系统的名称以及 URL-->
<issueManagement>
<!--问题管理系统名称-->
<system>jira</system>
<!--问题管理系统的 URL-->
<url></url>
</issueManagement>
<!--项目持续集成信息-->
<ciManagement>
<!--持续集成系统的名称-->
<system></system>
<!--持续集成系统的URL如果需要使用 CI 系统 Web 接口时使用-->
<url></url>
<!--构建完成时通知用户的配置,包括被通知者信息以及通知条件-->
<notifier>
<!--传递通知的路径-->
<type />
<!--发生错误时是否通知-->
<sendOnError />
<!--构建失败时是否通知-->
<sendOnFailure />
<!--构建成功时是否通知-->
<sendOnSuccess />
<!--产生警告时是否通知-->
<sendOnWarning />
<!--通知发送到的位置-->
<address />
<!--扩展配置-->
<configuration />
</notifier>
</ciManagement>
<!--项目创建年份,用于产生版权信息-->
<inceptionYear />
<!--项目开发者列表-->
<developers>
<!--单一开发者的描述信息-->
<developer>
<!--SCM 中的开发者唯一标识-->
<id></id>
<!--开发者的全名-->
<name></name>
<!--开发者的Email-->
<email></email>
<!--开发者的个人主页-->
<url></url>
<!--开发者在项目中的角色-->
<roles>
<role>Project Manager</role>
<role>Architect</role>
</roles>
<!--开发者所属组织-->
<organization></organization>
<!--开发者所属组织的主页-->
<organizationUrl></organizationUrl>
<!--开发者所在时区-->
<timezone></timezone>
</developer>
</developers>
<!--项目贡献者列表-->
<contributors>
<!--单一贡献者的描述信息,内容子元素与开发者一致-->
<contributor></contributor>
</contributors>
<!--项目所使用的许可列表,只列出项目的许可,不必包含依赖项的许可-->
<licenses>
<!--单一许可的描述-->
<license>
<!--许可名称-->
<name></name>
<!--官方许可正文页面的 URL-->
<url></url>
<!--项目分发方式,一般为可从 Maven 库下载-->
<distribution>repo</distribution>
<!--补充信息-->
<comments></comments>
</license>
</licenses>
<!--配置代码库,供 Maven Web 和其他插件使用-->
<scm>
<!--SCM 的 URL-->
<connection></connection>
<!--给开发者使用的 SCM 地址-->
<developerConnection></developerConnection>
<!--当前代码的标签,默认为 HEAD-->
<tag />
<!--项目的可浏览 SCM 库的 URL-->
<url></url>
</scm>
<!--项目所属组织的信息-->
<organization>
<!--组织全名-->
<name></name>
<!--组织的主页 URL-->
<url></url>
</organization>
<!--构建项目所需要的信息-->
<build>
<!--所有的目录信息都书写相对于 pom.xml 的路径-->
<!--项目源码目录,其中内容会被编译-->
<sourceDirectory></sourceDirectory>
<!--项目脚本源码目录,其中内容会被直接复制到输出目录-->
<scriptSourceDirectory></scriptSourceDirectory>
<!--单元测试使用的源码目录-->
<testSourceDirectory></testSourceDirectory>
<!--编译后的 class 文件存放目录-->
<outputDirectory></outputDirectory>
<!--编译后的测试 class 文件存放目录-->
<testOutputDirectory></testOutputDirectory>
<!--来自该项目的构建扩展-->
<extensions>
<!--使用到的构建扩展-->
<extension>
<!--扩展的GAV坐标-->
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</extension>
</extensions>
<!--项目默认目标-->
<defaultGoal />
<!--项目所有相关资源路径列表,资源最终将包含在打包文件中-->
<resources>
<!--描述项目的一个资源-->
<resource>
<!--资源相对于 target/classes 目录的目标路径-->
<targetPath></targetPath>
<!--是否使用参数值代替参数名-->
<filters />
<!--相对于 pom.xml 存放资源的目录路径-->
<directory></directory>
<!--包含列表-->
<includes></includes>
<!--排除列表-->
<excludes></excludes>
</resource>
</resources>
<!--项目单元测试所使用的资源路径列表,其中内容结构同项目资源路径-->
<testResources>
<testResource></testResource>
</testResources>
<!--构建产生的文件存放目录-->
<directory></directory>
<!--构建产生的文件名默认值为artifactId-version-->
<finalName></finalName>
<!--当filtering开关打开时使用到的过滤器属性文件列表 -->
<filters />
<!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置 -->
<pluginManagement>
<!--使用的插件列表 。 -->
<plugins>
<!--plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!--插件在仓库里的group ID -->
<groupId />
<!--插件在仓库里的artifact ID -->
<artifactId />
<!--被使用的插件的版本(或版本范围) -->
<version />
<!--是否从该插件下载Maven扩展例如打包和类型处理器由于性能原因只有在真需要下载时该元素才被设置成enabled。 -->
<extensions />
<!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!--execution元素包含了插件执行需要的信息 -->
<execution>
<!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标 -->
<id />
<!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段 -->
<phase />
<!--配置的执行目标 -->
<goals />
<!--配置是否被传播到子POM -->
<inherited />
<!--作为DOM对象的配置 -->
<configuration />
</execution>
</executions>
<!--项目引入插件所需要的额外依赖 -->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--依赖作用域-->
<scope></scope>
<!--依赖 Jar 包所在位置-->
<systemPath></systemPath>
</dependency>
</dependencies>
<!--任何配置是否被传播到子项目 -->
<inherited />
<!--作为DOM对象的配置 -->
<configuration />
</plugin>
</plugins>
</pluginManagement>
<!--使用的插件列表 -->
<plugins>
<plugin></plugin>
</plugins>
</build>
<!--在列的项目构建profile如果被激活会修改构建处理 -->
<profiles>
<!--根据环境参数或命令行参数激活某个构建处理 -->
<profile>
<!--构建配置的唯一标识符。即用于命令行激活也用于在继承时合并具有相同标识符的profile。 -->
<id />
<!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。profile的力量来自于它 能够在某些特定的环境中自动使用某些特定的值这些环境通过activation元素指定。activation元素并不是激活profile的唯一方式。 -->
<activation>
<!--profile默认是否激活的标志 -->
<activeByDefault />
<!--当匹配的jdk被检测到profile被激活。例如1.4激活JDK1.41.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。 -->
<jdk />
<!--当匹配的操作系统属性被检测到profile被激活。os元素可以定义一些操作系统相关的属性。 -->
<os>
<!--激活profile的操作系统的名字 -->
<name>Windows XP</name>
<!--激活profile的操作系统所属家族(如 'windows') -->
<family>Windows</family>
<!--激活profile的操作系统体系结构 -->
<arch>x86</arch>
<!--激活profile的操作系统版本 -->
<version>5.1.2600</version>
</os>
<!--如果Maven检测到某一个属性其值可以在POM中通过${名称}引用其拥有对应的名称和值Profile就会被激活。如果值 字段是空的那么存在属性名称字段就会激活profile否则按区分大小写方式匹配属性值字段 -->
<property>
<!--激活profile的属性的名称 -->
<name>mavenVersion</name>
<!--激活profile的属性的值 -->
<value>2.0.3</value>
</property>
<!--提供一个文件名通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在如果不存在则激活 profile。另一方面exists则会检查文件是否存在如果存在则激活profile。 -->
<file>
<!--如果指定的文件存在则激活profile。 -->
<exists></exists>
<!--如果指定的文件不存在则激活profile。 -->
<missing></missing>
</file>
</activation>
<!--构建项目所需要的信息。参见 build 元素 -->
<build></build>
<!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 -->
<modules />
<!--发现依赖和扩展的远程仓库列表。 -->
<repositories></repositories>
<!--发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository></pluginRepository>
</pluginRepositories>
<!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。 -->
<dependencies></dependencies>
<!--不赞成使用. 现在Maven忽略该元素. -->
<reports />
<!--该元素包括使用报表插件产生报表的规范。当用户执行"mvn site",这些报表就会运行。 在页面导航栏能看到所有报表的链接。参见reporting元素 -->
<reporting></reporting>
<!--参见dependencyManagement元素 -->
<dependencyManagement>
<dependencies></dependencies>
</dependencyManagement>
<!--参见distributionManagement元素 -->
<distributionManagement></distributionManagement>
<!--参见properties元素 -->
<properties />
</profile>
</profiles>
<!--模块(有时称作子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 -->
<modules />
<!--发现依赖和扩展的远程仓库列表。 -->
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!--如何处理远程仓库里发布版本的下载 -->
<releases>
<!--true或者false表示该仓库是否为下载某种类型构件发布版快照版开启。 -->
<enabled />
<!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是always一直daily默认每日intervalX这里X是以分钟为单位的时间间隔或者never从不-->
<updatePolicy />
<!--当Maven验证构件校验文件失败时该怎么做ignore忽略fail失败或者warn警告-->
<checksumPolicy />
</releases>
<!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置POM就可以在每个单独的仓库中为每种类型的构件采取不同的策略。例如可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
<snapshots>
<enabled />
<updatePolicy />
<checksumPolicy />
</snapshots>
<!--远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库 -->
<id>banseon-repository-proxy</id>
<!--远程仓库名称 -->
<name>banseon-repository-proxy</name>
<!--远程仓库URL按protocol://hostname/path形式 -->
<url>http://192.168.1.169:9999/repository/</url>
<!-- 用于定位和排序构件的仓库布局类型-可以是default默认或者legacy遗留。Maven 2为其仓库提供了一个默认的布局然而Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default默认还是legacy遗留-->
<layout>default</layout>
</repository>
</repositories>
<!--发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素 -->
<pluginRepository></pluginRepository>
</pluginRepositories>
<!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。 -->
<dependencies>
<dependency>
<!--依赖的group ID -->
<groupId>org.apache.maven</groupId>
<!--依赖的artifact ID -->
<artifactId>maven-artifact</artifactId>
<!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。 -->
<version>3.8.1</version>
<!-- 依赖类型默认类型是jar。它通常表示依赖的文件的扩展名但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应
尽管这也有例外。一些类型的例子jarwarejb-client和test-jar。如果设置extensions为 true就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。 -->
<type>jar</type>
<!-- 依赖的分类器。分类器可以区分属于同一个POM但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如如果你想要构建两个单独的构件成JAR一个使用Java 1.4编译器另一个使用Java 6编译器你就可以使用分类器来生成两个单独的JAR构件。 -->
<classifier></classifier>
<!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。 - compile :默认范围,用于编译 - provided类似于编译但支持你期待jdk或者容器提供类似于classpath - runtime: 在执行时需要使用 - test: 用于test任务时使用 - system: 需要外在提供相应的元素。通过systemPath来取得 - systemPath: 仅用于范围为system。提供相应的路径 - optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 -->
<scope>test</scope>
<!--仅供system范围使用。注意不鼓励使用这个元素并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径例如${java.home}。 -->
<systemPath></systemPath>
<!--当计算传递依赖时, 从依赖构件列表里列出被排除的依赖构件集。即告诉maven你只依赖指定的项目不依赖项目的依赖。此元素主要用于解决版本冲突问题 -->
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
<!--可选依赖如果你在项目B中把C依赖声明为可选你就需要在依赖于B的项目例如项目A中显式的引用对C的依赖。可选依赖阻断依赖的传递性。 -->
<optional>true</optional>
</dependency>
</dependencies>
<!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖必须描述group ID和 artifact ID信息如果group ID和artifact ID以外的一些信息没有描述则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。 -->
<dependencyManagement>
<dependencies></dependencies>
</dependencyManagement>
<!--项目分发信息在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。 -->
<distributionManagement>
<!--部署项目产生的构件到远程仓库需要的信息 -->
<repository>
<!--是分配给快照一个唯一的版本号由时间戳和构建流水号还是每次都使用相同的版本号参见repositories/repository元素 -->
<uniqueVersion />
<id></id>
<name></name>
<url></url>
<layout />
</repository>
<!--构件的快照部署到哪里?如果没有配置该元素,默认部署到 repository 元素配置的仓库参见distributionManagement/repository元素 -->
<snapshotRepository>
<uniqueVersion />
<id></id>
<name></name>
<url></url>
<layout />
</snapshotRepository>
<!--部署项目的网站需要的信息 -->
<site>
<!--部署位置的唯一标识符,用来匹配站点和 settings.xml 文件里的配置 -->
<id></id>
<!--部署位置的名称 -->
<name></name>
<!--部署位置的URL按protocol://hostname/path形式 -->
<url></url>
</site>
<!--项目下载页面的 URL。如果没有该元素用户应该参考主页。使用该元素的原因是帮助定位那些不在仓库里的构件由于license限制-->
<downloadUrl />
<!--如果构件有了新的 group ID 和 artifact ID构件移到了新的位置这里列出构件的重定位信息。 -->
<relocation>
<!--构件新的group ID -->
<groupId />
<!--构件新的artifact ID -->
<artifactId />
<!--构件新的版本号 -->
<version />
<!--显示给用户的,关于移动的额外信息,例如原因。 -->
<message />
</relocation>
<!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素因为这是工具自动更新的。有效的值有none默认converted仓库管理员从 Maven 1 POM 转换过来partner直接从伙伴Maven 2仓库同步过来deployed从Maven 2实例部署verified被核实时正确的和最终的-->
<status />
</distributionManagement>
<!--以值替代名称Properties 可以在整个 POM 中使用,也可以作为触发条件(见 settings.xml 配置文件里 activation 元素的说明)。格式是 <name>value</name>。 -->
<properties />
</project>
{% endcodeblock %}