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。