Maven pom.xml 文件详解
一、POM 基本概念
POM(Project Object Model,项目对象模型)是 Maven 的核心概念,它是一个 XML 文件,用于描述项目的各种属性、依赖关系和构建信息。POM 文件是 Maven 工程的基本工作单元,包含了项目的所有必要信息,使 Maven 能够自动化地构建和管理项目。
每个 Maven 项目都只有一个 pom.xml 文件,位于项目的根目录中。
二、POM 文件基本结构
一个完整的 POM 文件结构如下:
xml
<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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 模型版本,Maven 2 和 3 只能是 4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- 基本配置 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<!-- 依赖配置 -->
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- 构建配置 -->
<build>...</build>
<reporting>...</reporting>
<!-- 项目信息 -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- 环境设置 -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
三、核心元素详解
1. 基本配置元素
modelVersion
指定 POM 模型的版本,对于 Maven 2 和 Maven 3,必须是 4.0.0 。
xml
<modelVersion>4.0.0</modelVersion>
groupId、artifactId、version
这三个元素共同构成了项目的唯一标识符,被称为"坐标",用于在 Maven 仓库中定位项目。
- groupId:组织或公司的唯一标识符,通常使用反向域名格式
- artifactId:项目的唯一标识符,通常是项目名称
- version:项目的版本号
xml
<groupId>com.example</groupId>
<artifactId>demo-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
packaging
指定项目的打包方式,常见的值有:
- jar:默认值,打包成 JAR 文件
- war:打包成 WAR 文件(Web 应用)
- pom:用于父项目或聚合项目
- ear:企业应用归档文件
xml
<packaging>jar</packaging>
2. 依赖管理元素
dependencies
定义项目的依赖列表,包含一个或多个 dependency 元素。
xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
<scope>compile</scope> <!-- 依赖范围 -->
<optional>false</optional> <!-- 是否可选依赖 -->
<exclusions> <!-- 排除依赖 -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
dependencyManagement
用于统一管理依赖版本,子项目可以继承父项目中的依赖配置,但不会自动引入依赖,需要在子项目中显式声明 。
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
</dependencies>
</dependencyManagement>
parent
用于指定父项目,实现配置继承。
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- 默认为 ../pom.xml -->
</parent>
properties
定义可重用的属性变量,可以通过 ${变量名}
的方式引用。
xml
<properties>
<spring.version>5.3.20</spring.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
3. 构建设置元素
build
包含项目构建相关的配置,如源代码目录、测试代码目录、插件配置等。
xml
<build>
<!-- 项目的最终名称 -->
<finalName>demo-project</finalName>
<!-- 资源文件配置 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<!-- 插件配置 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
4. 多模块项目配置
modules
用于聚合多个子模块,实现多模块项目管理。
xml
<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-3</module>
</modules>
四、依赖管理高级概念
1. 依赖范围(Scope)
依赖范围控制依赖在哪些阶段有效,常见的依赖范围有:
范围 | 说明 | 编译时 | 测试时 | 运行时 | 打包时 |
---|---|---|---|---|---|
compile | 默认范围,编译、测试、运行都有效 | ✅ | ✅ | ✅ | ✅ |
provided | 编译和测试有效,运行时由容器提供 | ✅ | ✅ | ❌ | ❌ |
runtime | 测试和运行有效,编译不需要 | ❌ | ✅ | ✅ | ✅ |
test | 仅测试有效 | ❌ | ✅ | ❌ | ❌ |
system | 类似 provided,但需要显式指定路径 | ✅ | ✅ | ❌ | ❌ |
import | 仅用于 dependencyManagement 中,导入依赖 | ❌ | ❌ | ❌ | ❌ |
2. 依赖传递性
Maven 具有依赖传递的特性,如果项目 A 依赖于项目 B,而项目 B 又依赖于项目 C,那么 Maven 会自动将项目 C 引入到项目 A 中 。
3. 依赖冲突解决
当项目中引入的多个依赖包含同一个 jar 包的不同版本时,Maven 会通过以下策略解决冲突:
-
路径优先:引用路径越短的依赖优先级越高
- 例如:A -> B -> C(v1.0) 和 A -> C(v2.0),则使用 v2.0
-
声明优先:当引用路径长度相同时,在 pom.xml 中声明顺序靠前的依赖优先级高
- 在 dependencies 标签中先声明的依赖会被优先使用
4. 排除依赖和可选依赖
排除依赖
如果不想引入传递依赖中的某个 jar 包,可以使用 exclusions 标签排除:
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
可选依赖
如果希望某个依赖不被传递给引用当前项目的其他项目,可以使用 optional 标签:
xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<optional>true</optional>
</dependency>
五、POM 的继承与聚合
1. 继承
子项目可以继承父项目的配置,避免重复配置。父项目的 packaging 必须为 pom 。
父项目配置:
xml
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<!-- 公共依赖配置 -->
</dependencies>
</dependencyManagement>
子项目配置:
xml
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<relativePath>../parent-project/pom.xml</relativePath>
</parent>
<artifactId>child-project</artifactId>
<!-- 可以省略 groupId 和 version,会继承父项目的 -->
2. 聚合
使用聚合可以将多个相关的项目作为一个整体进行构建,在父项目中使用 modules 标签 。
xml
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-3</module>
</modules>
六、仓库配置
1. 远程仓库配置
可以在 pom.xml 中配置远程仓库,用于下载依赖:
xml
<repositories>
<repository>
<id>aliyun</id>
<name>Aliyun Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2. 插件仓库配置
用于配置插件的远程仓库:
xml
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<name>Aliyun Plugin Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
七、Profiles 配置
Profiles 用于定义不同环境的配置,可以根据需要激活不同的 profile:
xml
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<environment>development</environment>
<db.url>jdbc:mysql://localhost:3306/dev_db</db.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<environment>production</environment>
<db.url>jdbc:mysql://prod-server:3306/prod_db</db.url>
</properties>
</profile>
</profiles>
激活 profile 的方式:
bash
mvn clean install -Pprod
八、实用技巧
-
使用属性统一管理版本号:
xml<properties> <spring.version>5.3.20</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
-
使用 Spring Boot 父项目简化配置:
xml<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.7</version> </parent>
-
查看依赖树:
bashmvn dependency:tree
-
排除所有传递依赖:
xml<dependency> <groupId>com.example</groupId> <artifactId>some-lib</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
总结
pom.xml 是 Maven 项目的核心配置文件,通过合理配置 pom.xml,可以有效地管理项目依赖、控制构建过程、实现多模块项目管理等。掌握 pom.xml 的配置技巧,对于提高 Maven 使用效率和项目管理水平至关重要。本文详细介绍了 pom.xml 的结构和各元素的功能,希望能帮助开发者更好地理解和使用 Maven。