观察我们创建的项目就可以发现,无论是父模块还是子模块,都包含一个pom.xml配置文件,接下来我们将要学习POM的相关知识。
项目对象模型(Project Object Model)也成为POM,是Maven项目的基本单位。
POM是以.xml配置文件的形式存在于项目中的,它包含了项目信息以及构建项目的配置详情。当项目去执行一个任务或目标时,Maven会在当前目录寻找POM并且读取信息以及配置,最后去执行相应的功能。
POM可以指定配置信息,如项目的依赖,插件等,也可以制定项目的信息,如版本、描述,开发人员等,可以说没有POM就没有Maven。
1. 快速预览
以下是POM元素的清单
<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">
<modelVersion>4.0.0</modelVersion>
<!-- The Basics -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
可以看到,官方给这些元素分为几部分
- 基础元素 The Basics
- 构建设置 Build Settings
- 项目额外信息 More Project Infomation
- 环境设置 Environment Settings
2. 基础元素
2.1 最少配置项
POM至少应该包含如下内容
project: 整个POM的根modelVersion:模型版本,现在都是固定4.0.0groupId:项目所属组的ID,一般为项目所属的公司、机构、个人的名称/网站倒叙 + 项目所属租名,如org.springframework.boot,com.google.guava。
其中spring的网站为http://springframework.org,与现在的http://spring.io通用,倒过来就是org.springframework,项目为spring boot所属组名为boot,所以完整的groupId为org.springframework.boot。guava也同理artifactId:制品ID,可以理解为项目名。如spring-core、spring-context、spring-bean等version:该artifact的版本
以上元素都是POM中必须存在的。(在后续将要学习的继承关系中,有些元素可以省略,因为他们从父模块中继承)
其中groupId、artifactId以及version这三个值组合在一起就构成了该项目或模块的全限定名,采用<groupId>:<artifactId>:<version>的格式来表示,Maven可以根据全限定名来找寻我们想要的jar包等。
比如之前我们创建的简单Mavendemo中自动创建的POM如下

我们将不需要的配置删掉,只留下最低配置

这个POM描述了该项目的信息
首先是一个根标签<project>;接下来值是固定4.0.0的<modelVersion>标签;<groupId>表明该项目所属的机构/个人以及group为org.example;<artifactId>标签说明了该项目的名称;<version>表明了该项目的版本。所以该artifact的全限定名为org.example:maven-demo:1.0-SNAPSHOT
2.2 packaging
我们的程序编写完之后,并不能像我们开发一样在IDEA中运行,需要将他们打包成指定的制品。比如可能给其他人在项目里直接引用的jar包,或是可以在Tomcat中运行的web项目war包。这时候就需要在POM中定义packaging元素来告诉Maven我们想要什么。
<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">
...
<packaging>war</packaging>
...
</project>
上述例子中就是通知Maven我们要项目打包成war包。
2.2.1 默认值以及可选值
packaging标签是可选标签,如果不进行声明,那么默认的打包方式为jar。
目前可选值有pom、jar、maven-plugin、ejb、war、ear以及rar。
2.2.2 示例
首先测试默认打包方式。
创建一个简单maven项目pom-basic,配置如下所示

待项目生成完毕之后,将pom.xm精简为最小配置项,并且删掉src下的test文件夹。


在IDEA右侧点击Maven窗口,展开树结构菜单,进入Lifecycle,右键package,选择Run或者Debug,等待程序执行。


观察控制台输出,Maven在指定的target文件夹下将程序打包成了jar包。
接下来测试打包成指定的方式
我们在pom.xml中配置packaging标签,指定打包方式

之后再点击右侧的Maven窗口右键点击package,观察控制台输出

可以看到Maven已经将项目打包成我们想要的方式了。
2.3 POM关系
Maven的一个强大方面就是处理项目之间的关系:包括依赖关系(dependency)、继承关系(inheritance)以及聚合关系(aggregation)。
2.3.1 依赖关系denpendency
POM的基石就是依赖,大多数的项目都必须要使用第三方的jar才能够运行,比如每个项目都在用的spring框架,那么就需要依赖spring的jar。之前的方法是我们需要自己去下载这些jar,问题就是这种做法非常麻烦,而且如果jar的版本也会非常乱。
Maven会帮助我们去管理这些jar,包括下载所需要的jar以及这些jar依赖的jar。
依赖关系的定义结构如下
<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">
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<classifier>jdk8</classifier>
<optional>true</optional>
</dependency>
...
</dependencies>
...
</project>
所有依赖的根节点
每一个依赖用一组<dependency>来定义。
使用权限定名,即groupId:artifactId:version坐标来指定具体的依赖以及其版本。
Maven会从中央仓库中下载这些jar以及这些jar依赖的jar到我们的本地仓库,下载的完整路径见本地仓库章节。
译为分类。可以是任意字符,该标签存在的意义是同一个Maven坐标下还可以再细分小“版本”,或还有不同的制品,如json-lib,它的每个版本下分为不同的jdk版本,如下所示

坐标都为net.sf.json-lib:json-lib:2.4,但是却分为jdk13版本、jdk15版本,而每个版本下还分javadoc版本和sources版本。可以看出classfier是附在version之后的,那么坐标就变为groupId:artifactId:version:classfier,jar的名称也变为了artifactId-version-classfier.jar了。上述例子中,如果我们要使用jdk13版本,那么应该按照如下方式定义dependency
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classfier>jdk13</classfier>
</dependency>
type
选择依赖的类型,默认为jar,通常为文件或依赖的扩展名。但是也有例外,如test-jar、ejb-client,这些类型的扩展名就与type不同,官网给出了区别与联系Default Artifact Handlers Reference。
比如一个dependency下既有jar类型还有war类型,那么就需要指定type来选择我们想要的依赖
scope
了解scope之前,先要了解依赖传递,可以看以下另一篇文章 // TODO
该依赖的生效范围,一共有六种scope
compile(默认):在所有classpath下都可以可用,并且依赖关系会传播到依赖的项目中provided:希望JDK或其他容器在运行时提供,只在编译以及测试的classpath下可用,没有传播性runtime:表明编译期间不需要该依赖,但是运行时需要。在运行以及测试classpath下可用,编译classpath下不可用。test:表明项目中并不会依赖次dependency,只在测试classpath中生效,也就是在测试模块中会使用到,没有传播性system:
2.3.1.1 中央仓库
2.3.1.2 本地仓库
我们之前层在Maven的配置文件setting.xml中添加了本地仓库地址,我们来观察一下本地仓库。






不难发现,Maven将jar下载到了它在Maven中的坐标的相对路径文件夹。
上面的例子中,文件夹为org/springframework/boot/spring-boot-starter/2.5.2/spring-boot-starter-2.5.2.jar
而spring-boot-starter的坐标为
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.2</version>
</dependency>
我们可以总结出a
本文详细介绍了Maven的项目对象模型(POM),包括其作为项目基本单位的作用,POM文件的结构和内容,如模型版本、基础元素(groupId、artifactId、version和packaging)、依赖管理以及环境设置。POM用于定义项目信息、构建设置和依赖关系,使得Maven能够自动化构建和管理项目。通过实例展示了如何配置POM以指定项目打包方式和依赖。
1764

被折叠的 条评论
为什么被折叠?



