Maven配置文件(pom.xml)终极指南

这是一份非常详细、实用、通俗易懂、权威且全面的 Maven 配置文件 (pom.xml) 全面指南。


Maven 配置文件 (pom.xml) 全面指南

目录

  1. Maven 与 pom.xml 简介

    • 1.1 什么是 Maven?
    • 1.2 pom.xml 的核心作用
    • 1.3 项目对象模型 (POM) 概念
  2. pom.xml 文件结构详解

    • 2.1 根元素:<project>
    • 2.2 基础坐标:<groupId>, <artifactId>, <version> (GAV)
    • 2.3 项目元信息:<name>, <description>, <url>, <inceptionYear>, <organization>, <licenses>
    • 2.4 父项目继承:<parent>
    • 2.5 依赖管理:<dependencies><dependency>
      • 2.5.1 依赖坐标 (GAV)
      • 2.5.2 依赖作用域 (<scope>)
      • 2.5.3 可选依赖 (<optional>)
      • 2.5.4 排除传递依赖 (<exclusions>)
    • 2.6 依赖管理优化:<dependencyManagement>
    • 2.7 构建配置:<build>
      • 2.7.1 默认生命周期与插件
      • 2.7.2 插件管理:<pluginManagement>
      • 2.7.3 插件配置:<plugins><plugin>
      • 2.7.4 资源管理:<resources><resource>
      • 2.7.5 测试资源管理:<testResources><testResource>
      • 2.7.6 输出目录配置 (<directory>)
      • 2.7.7 最终名称 (<finalName>)
    • 2.8 报告配置:<reporting>
    • 2.9 属性定义:<properties>
    • 2.10 多模块项目:<modules>
    • 2.11 环境配置:<profiles>
      • 2.11.1 激活条件 (<activation>)
      • 2.11.2 配置覆盖
  3. pom.xml 核心元素最佳实践

    • 3.1 GAV 命名规范
    • 3.2 依赖管理策略 (<dependencyManagement> 的使用)
    • 3.3 插件管理策略 (<pluginManagement> 的使用)
    • 3.4 <scope> 的合理使用
    • 3.5 利用 <properties> 管理公共值
    • 3.6 Profile 的适用场景
  4. 实战案例:可直接在 IDE 中运行的系统示例

    • 案例一:基础 Java 项目
      • 4.1 项目描述
      • 4.2 pom.xml 完整代码
      • 4.3 核心配置点解析
      • 4.4 如何运行 (命令行 & IDE)
    • 案例二:Spring Boot Web 应用
      • 4.5 项目描述
      • 4.6 pom.xml 完整代码
      • 4.7 核心配置点解析 (继承、Spring Boot 插件)
      • 4.8 如何运行 (启动应用)
    • 案例三:多模块项目 (Parent POM + 子模块)
      • 4.9 项目结构描述
      • 4.10 父模块 pom.xml 完整代码 (管理依赖和插件)
      • 4.11 子模块 (如 core, web) pom.xml 示例代码
      • 4.12 核心配置点解析 (<modules>, <parent>, <dependencyManagement>, <pluginManagement>)
      • 4.13 如何构建整个项目
  5. 常见问题解答 (FAQ)

    • 5.1 如何解决依赖冲突?
    • 5.2 如何覆盖父 POM 中的配置?
    • 5.3 如何查看项目的完整依赖树?
    • 5.4 如何跳过测试 (mvn install -DskipTests)?
    • 5.5 pom.xml 中的变量 (${...}) 是如何解析的?
  6. 总结


1. Maven 与 pom.xml 简介

  • 1.1 什么是 Maven? Maven 是一个强大的项目构建依赖管理 工具。它使用基于项目对象模型 (POM) 的概念来管理项目的构建、报告和文档。Maven 的核心思想是约定优于配置,它定义了一套标准的项目结构和构建生命周期,简化了构建过程。

  • 1.2 pom.xml 的核心作用 pom.xml (Project Object Model) 是 Maven 项目的核心配置文件,通常位于项目的根目录下。它包含了 Maven 构建项目所需的所有信息和配置,相当于项目的"蓝图"。其主要作用包括:

    • 定义项目的基本信息(名称、描述、版本等)。
    • 管理项目所依赖的第三方库(JAR 包)。
    • 配置构建过程中使用的插件(如编译插件、测试插件、打包插件等)。
    • 定义构建生命周期(clean, compile, test, package, install, deploy 等阶段)。
    • 支持多模块项目的管理。
    • 允许通过 Profile 进行环境特定的配置。
  • 1.3 项目对象模型 (POM) 概念 POM 是一个 XML 文件,它抽象地描述了一个项目。pom.xml 就是这个模型的具体实现文件。Maven 在构建项目时,会读取 pom.xml,根据其中的配置执行相应的操作。所有 Maven 项目都隐式地继承自一个超级 POM ,它包含了 Maven 的默认配置。你的 pom.xml 可以覆盖或扩展这些默认配置。

2. pom.xml 文件结构详解

一个完整的 pom.xml 文件遵循以下基本结构:

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">
    <!-- 模型版本 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 基础坐标 -->
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <!-- 打包类型 -->
    <packaging>jar</packaging> <!-- 默认是 jar, 还有 war, pom 等 -->

    <!-- 项目元信息 (可选) -->
    <name>My Awesome Project</name>
    <description>A project demonstrating Maven POM configuration</description>
    <url>http://www.example.com/projects/my-project</url>
    <inceptionYear>2023</inceptionYear>
    <organization>
        <name>Example Inc.</name>
        <url>http://www.example.com</url>
    </organization>
    <licenses>
        <license>
            <name>The Apache License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <!-- 父项目继承 (可选) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- 通常留空,表示从本地仓库或远程仓库查找 -->
    </parent>

    <!-- 依赖列表 -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 更多依赖... -->
    </dependencies>

    <!-- 依赖管理 (常用于父POM或BOM) -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>spring-platform-bom</artifactId>
                <version>Brussels-SR7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 构建配置 -->
    <build>
        <!-- 插件列表 -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <!-- 更多插件... -->
        </plugins>
        <!-- 插件管理 (常用于父POM) -->
        <pluginManagement>
            <plugins>...</plugins>
        </pluginManagement>
        <!-- 资源管理 -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering> <!-- 是否替换资源文件中的属性占位符 -->
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
        <!-- 测试资源管理 -->
        <testResources>...</testResources>
        <!-- 输出目录配置 -->
        <directory>${project.basedir}/target</directory> <!-- 默认值 -->
        <outputDirectory>${project.build.directory}/classes</outputDirectory>
        <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
        <!-- 最终打包名称 -->
        <finalName>${project.artifactId}-${project.version}</finalName>
    </build>

    <!-- 报告配置 (主要用于生成站点文档) -->
    <reporting>
        <plugins>...</plugins>
    </reporting>

    <!-- 属性定义 -->
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>3.1.0</spring-boot.version>
    </properties>

    <!-- 多模块项目声明 -->
    <modules>
        <module>core-module</module>
        <module>web-module</module>
    </modules>

    <!-- 环境配置 (Profiles) -->
    <profiles>
        <profile>
            <id>development</id>
            <activation>
                <activeByDefault>true</activeByDefault> <!-- 默认激活 -->
            </activation>
            <properties>
                <env>dev</env>
            </properties>
        </profile>
        <profile>
            <id>production</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>prod</value>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <skipTests>true</skipTests> <!-- 生产环境跳过测试 -->
                        </configuration>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <env>prod</env>
            </properties>
        </profile>
    </profiles>
</project>

下面详细解释关键部分:

  • 2.1 根元素:<project> 这是整个 pom.xml 文件的根元素,包含了 XML 命名空间和 Schema 定义,用于验证 XML 结构。

  • 2.2 基础坐标:<groupId>, <artifactId>, <version> (GAV) 这三个元素构成了项目的唯一标识符 ,被称为 GAV 坐标。它们在 Maven 世界中至关重要。

    • <groupId>: 通常代表组织或项目组,使用反向域名规则 (如 com.example, org.apache)。它定义了项目在仓库中的路径。
    • <artifactId>: 项目的唯一标识符。通常是项目名称 (如 my-project, spring-core)。
    • <version>: 项目的当前版本。常用格式如 1.0.0, 2.3.1-SNAPSHOTSNAPSHOT 表示开发中的快照版本。
    • <packaging>: 定义项目构建后生成的主要构件类型。默认为 jar。常见值:jar (Java库), war (Web应用), pom (父项目或多模块聚合), ear (企业应用)。
  • 2.3 项目元信息 这些元素提供项目的描述性信息,对于生成项目文档或站点很有用。都是可选的。

    • <name>: 项目的人类可读名称。
    • <description>: 项目的详细描述。
    • <url>: 项目主页的 URL。
    • <inceptionYear>: 项目开始的年份。
    • <organization>: 负责项目的组织信息。
    • <licenses>: 项目使用的许可证列表。
  • **2.4 父项目继承:<parent> 允许当前项目继承另一个项目(通常是父 POM)的配置。这是实现统一配置(如依赖版本、插件配置)的重要手段。

    • <groupId>, <artifactId>, <version>: 父项目的 GAV 坐标。
    • <relativePath>: 指定父 pom.xml 相对于当前项目的路径。通常留空 <relativePath/>,表示 Maven 应先在本地仓库查找父 POM,再到远程仓库查找。如果父项目就在当前项目的父目录中(如在多模块项目中),可以设置路径如 ../pom.xml
  • **2.5 依赖管理:<dependencies><dependency> 这是 pom.xml 的核心部分之一,声明项目编译、测试、运行等阶段所需的库。

    • 2.5.1 依赖坐标 (GAV) : 每个 <dependency> 内部必须包含 <groupId>, <artifactId>, <version> 来指定依赖的库。如果继承了父 POM 且父 POM 的 <dependencyManagement> 中定义了该依赖的版本,则子 POM 可以省略 <version>

    • 2.5.2 依赖作用域 (<scope>) : 定义依赖在哪些阶段可用。非常重要!

      • compile (默认): 编译、测试、运行时都需要。会打包到最终构件中。
      • provided: 编译和测试时需要,但运行时由容器(如 Tomcat、JDK)提供。不会打包到最终构件中 (如 servlet-api)。
      • runtime: 不需要编译,但需要用于测试和运行。会打包到最终构件中 (如 JDBC 驱动)。
      • test: 仅用于测试的编译和执行阶段 (如 JUnit)。
      • system: 类似于 provided,但需要显式指定一个系统路径下的 JAR。不推荐使用,不利于可移植性。
      • import: 仅用于 <dependencyManagement> 中的 <type>pom</type> 依赖,表示导入该 POM 中 <dependencyManagement> 的配置。
    • 2.5.3 可选依赖 (<optional>) : 设置为 true 表示该依赖是可选的。即使其他项目依赖于你的项目,这个可选依赖也不会被传递下去。用于解决潜在冲突。

    • 2.5.4 排除传递依赖 (<exclusions>) : 当你引入依赖 A,A 又依赖 B (传递依赖),但你不想要 B 或者 B 的版本与你的项目冲突时,可以在依赖 A 的声明中排除 B。

      XML 复制代码
      <dependency>
          <groupId>com.example</groupId>
          <artifactId>library-a</artifactId>
          <version>1.0</version>
          <exclusions>
              <exclusion>
                  <groupId>com.conflicting</groupId>
                  <artifactId>library-b</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
  • 2.6 依赖管理优化:<dependencyManagement> 这个元素通常用于 父 POM** 或 BOM (Bill of Materials) 项目中。它本身并不引入依赖,而是声明依赖及其版本 。子项目在 <dependencies> 中声明依赖时,如果该依赖在父 POM 的 <dependencyManagement> 中定义过,就可以省略 <version> (有时也可以省略 <scope>),由父 POM 统一管理版本。这极大地简化了依赖版本管理,确保多模块项目中依赖版本一致。

    • import scope: 用于导入另一个 POM 的 <dependencyManagement> 配置。

      XML 复制代码
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>io.spring.platform</groupId>
                  <artifactId>spring-platform-bom</artifactId>
                  <version>Brussels-SR7</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>
  • 2.7 构建配置: <build> 配置项目构建过程的细节。

    • 2.7.1 默认生命周期与插件 : Maven 的生命周期 (clean, default, site) 由一系列阶段 (phase) 组成。每个阶段默认绑定了一个或多个插件目标 (goal)。例如,compile 阶段默认绑定 maven-compiler-plugincompile 目标。

    • 2.7.2 插件管理:<pluginManagement> : 类似于 <dependencyManagement>,通常用于父 POM。它声明插件及其配置,但不实际引入插件。子项目在 <plugins> 中声明插件时,如果父 POM 的 <pluginManagement> 中有定义,可以继承配置或版本。

    • 2.7.3 插件配置:<plugins><plugin> : 实际引入并配置项目构建所需的插件。每个 <plugin> 需要 <groupId>, <artifactId>, 通常还有 <version>。可以在 <configuration> 子元素中定制插件行为。

      XML 复制代码
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.11.0</version>
              <configuration>
                  <source>17</source> <!-- Java 源代码版本 -->
                  <target>17</target> <!-- 生成的目标 class 文件版本 -->
                  <encoding>${project.build.sourceEncoding}</encoding> <!-- 编码 -->
              </configuration>
          </plugin>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <configuration>
                  <mainClass>com.example.MyApplication</mainClass> <!-- 指定启动类 -->
              </configuration>
          </plugin>
      </plugins>
    • 2.7.4 资源管理:<resources> : 配置哪些文件从 src/main/resources 目录复制到输出目录 (target/classes)。可以指定 <filtering> (是否替换属性占位符), <includes>, <excludes> 来精细控制。

    • 2.7.5 测试资源管理:<testResources> : 类似 <resources>,但针对 src/test/resources 目录,复制到 target/test-classes

    • 2.7.6 输出目录配置 : 可以自定义输出路径(通常不建议修改默认约定)。

      • <directory>: 整个构建的根输出目录 (默认 target)。
      • <outputDirectory>: 主代码编译输出目录 (默认 target/classes)。
      • <testOutputDirectory>: 测试代码编译输出目录 (默认 target/test-classes)。
    • 2.7.7 最终名称 (<finalName>) : 定义打包后生成的主构件的文件名(不包括扩展名)。默认是 ${project.artifactId}-${project.version}。例如,设置为 myapp 后,打包生成的 JAR 将是 myapp.jar (对于 jar 打包类型)。

  • 2.8 报告配置:<reporting> 配置在生成项目站点 (mvn site) 时使用的报告插件。例如 Javadoc 报告、测试报告、代码覆盖率报告等。

  • 2.9 属性定义:<properties> 定义自定义属性,可以在 pom.xml 的其他地方通过 ${property.name} 引用。常用于:

    • 定义公共版本号 (如 <spring.version>5.3.9</spring.version>)。
    • 定义构建参数 (如 <java.version>17</java.version>,然后在编译器插件中引用)。
    • 定义编码 (<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>)。
  • 2.10 多模块项目:<modules> 用于聚合项目 (通常打包类型为 pom)。它列出了该项目包含的所有子模块。子模块通常是当前项目的子目录。Maven 命令在父项目执行时,会递归地在所有子模块上执行。

    XML 复制代码
    <modules>
        <module>core</module> <!-- 子模块目录名 -->
        <module>service</module>
        <module>webapp</module>
    </modules>

    子模块需要通过 <parent> 元素指向父项目。

  • 2.11 环境配置:<profiles> 允许定义不同的构建配置集,这些配置集可以根据特定条件(环境变量、操作系统、文件是否存在等)激活。非常灵活!

    • 2.11.1 激活条件 (<activation>) : 定义何时自动激活该 Profile。
      • <activeByDefault>: 是否默认激活。
      • <jdk>: 匹配特定 JDK 版本时激活。
      • <os>: 匹配特定操作系统时激活。
      • <property>: 当某个属性(系统属性或 POM 属性)存在或等于特定值时激活。
      • <file>: 当某个文件存在或缺失时激活。
    • 2.11.2 配置覆盖 : Profile 内部可以定义 <dependencies>, <dependencyManagement>, <build>, <properties>, <repositories>, <pluginRepositories> 等。当 Profile 激活时,这些配置会与主 POM 的配置合并或覆盖主 POM 的配置。Profile 中的 <build> 配置会覆盖主 POM 的 <build> 配置。
    XML 复制代码
    <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>dev</value>
                </property>
            </activation>
            <properties>
                <log.level>DEBUG</log.level>
            </properties>
        </profile>
        <profile>
            <id>prod</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>prod</value>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <skipTests>true</skipTests>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <log.level>WARN</log.level>
            </properties>
        </profile>
    </profiles>

    激活 Profile 的方法:

    • 命令行: mvn clean install -P dev,prod (激活 id 为 devprod 的 Profile)。
    • 命令行 (属性激活): mvn clean install -Denv=prod
    • settings.xml 中配置。
    • IDE 通常提供界面选择激活的 Profile。

3. pom.xml 核心元素最佳实践

  • 3.1 GAV 命名规范

    • groupId: 使用组织或项目的域名反转 (e.g., com.company, org.opensource.project)。
    • artifactId: 简洁、有意义,通常使用小写字母和连字符 (e.g., user-service, data-model)。
    • version: 遵循语义化版本控制 (major.minor.patch),快照版本用 SNAPSHOT 后缀。避免使用 final, release 等非标准后缀。
  • 3.2 依赖管理策略

    • 优先使用 <dependencyManagement> : 尤其是在多模块项目中,父 POM 统一管理依赖版本,子模块只需声明 <groupId><artifactId>,确保版本一致,减少冲突。
    • 利用 BOM : 对于大型框架 (如 Spring Boot, Jakarta EE),使用其提供的 BOM (<type>pom</type>, <scope>import</scope>) 来管理相关依赖的兼容版本。
    • 明确指定 <scope>: 根据依赖的实际用途设置正确的 Scope,避免不必要的依赖传递和打包。
    • 定期检查依赖 : 使用 mvn dependency:tree 查看依赖树,mvn versions:display-dependency-updates 检查可用更新。移除未使用的依赖 (mvn dependency:analyze)。
  • 3.3 插件管理策略

    • 在父 POM 的 <pluginManagement> 中统一管理常用插件的版本和基础配置。
    • 在子模块的 <plugins> 中引用这些插件,必要时进行覆盖或补充配置。
  • 3.4 <scope> 的合理使用

    • 仔细评估每个依赖的作用域。滥用 compile 会导致最终包过大或冲突。正确使用 providedtest 能显著优化项目。
  • 3.5 利用 <properties> 管理公共值

    • 将重复使用的值(尤其是版本号、目录路径、编码、JDK 版本)定义为属性。
    • 便于统一修改和维护。
  • 3.6 Profile 的适用场景

    • 环境差异化配置: 开发环境 (DEBUG 日志, H2 数据库), 测试环境, 生产环境 (WARN 日志, MySQL, 跳过测试)。
    • 操作系统特定配置: Windows 和 Linux 下的路径差异。
    • 功能开关: 启用或禁用某些构建步骤或插件。
    • 谨慎使用 : Profile 会增加配置复杂性。优先考虑通过外部配置(如 application.properties)管理运行时差异。Profile 更适合管理构建过程本身的差异。

4. 实战案例:可直接在 IDE 中运行的系统示例

案例一:基础 Java 项目

  • 4.1 项目描述: 一个简单的 Java 命令行应用程序,使用 JUnit 进行测试。
  • 4.2 pom.xml 完整代码:
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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.basic</groupId>
    <artifactId>java-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Basic Java Demo</name>
    <description>A simple Java command-line application built with Maven.</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>11</java.version>
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        <!-- JUnit for testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Compiler plugin to set Java version -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <!-- Jar plugin to create executable JAR (if needed) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <!-- If you want an executable jar, specify main class -->
                    <!-- <archive>
                        <manifest>
                            <mainClass>com.example.basic.App</mainClass>
                        </manifest>
                    </archive> -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • 4.3 核心配置点解析 :
    • 定义了 GAV 坐标。
    • 使用 <properties> 管理 Java 版本、编码和 JUnit 版本。
    • 依赖 JUnit (<scope>test</scope>)。
    • 配置 maven-compiler-plugin 指定源代码和目标字节码版本。
    • 包含了 maven-jar-plugin (配置被注释,如需可执行 JAR 需取消注释并设置 <mainClass>)。
  • 4.4 如何运行 :
    • 命令行 :
      • 编译: mvn compile
      • 测试: mvn test
      • 打包: mvn package (生成 target/java-demo-1.0.0-SNAPSHOT.jar)
    • IDE (如 IntelliJ IDEA, Eclipse) :
      1. 导入项目 (选择包含 pom.xml 的文件夹)。
      2. Maven 配置会自动加载。
      3. 编写 src/main/java/com/example/basic/App.java (包含 main 方法)。
      4. 编写 src/test/java/com/example/basic/AppTest.java (JUnit 测试)。
      5. 右键运行 App.javaAppTest.java。使用 IDE 的 Maven 工具窗口执行 Maven 命令。

案例二:Spring Boot Web 应用

  • 4.5 项目描述: 一个使用 Spring Boot 创建的简单 RESTful Web 服务。
  • 4.6 pom.xml 完整代码:
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">
    <modelVersion>4.0.0</modelVersion>

    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version> <!-- Check for latest version -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example.boot</groupId>
    <artifactId>springboot-web-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring Boot Web Demo</name>
    <description>Demo project for Spring Boot Web</description>
    <packaging>jar</packaging> <!-- Spring Boot executable jar -->

    <properties>
        <java.version>17</java.version> <!-- Override parent's default if needed -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Spring Boot Web Starter (includes embedded Tomcat, Spring MVC) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Boot Test Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Essential: Spring Boot Maven Plugin for creating executable jar/war and running -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 4.7 核心配置点解析 :
    • 继承 spring-boot-starter-parent: 继承 Spring Boot 的默认配置(依赖管理、插件管理等)。
    • 依赖 spring-boot-starter-web: 引入 Spring MVC 和嵌入式 Tomcat 等 Web 开发所需依赖。版本由父 POM 管理。
    • 依赖 spring-boot-starter-test : 引入 Spring Test 和 JUnit 等测试依赖 (<scope>test</scope>)。
    • 必备插件 spring-boot-maven-plugin : 这个插件是 Spring Boot 应用的核心。它负责:
      • 将应用打包成一个可执行的 JAR/WAR 文件(包含所有依赖和嵌入式容器)。
      • 提供 spring-boot:run 目标,用于在开发时快速启动应用。
  • 4.8 如何运行 :
    • 命令行 :
      • 运行: mvn spring-boot:run (使用插件启动应用)。
      • 打包: mvn package (生成可执行 JAR target/springboot-web-demo-0.0.1-SNAPSHOT.jar)。
      • 运行 JAR: java -jar target/springboot-web-demo-0.0.1-SNAPSHOT.jar.
    • IDE :
      1. 导入项目。
      2. 找到主类 (通常带有 @SpringBootApplication 注解,如 src/main/java/com/example/boot/Application.java)。
      3. 右键运行该主类 (IDE 会识别为 Spring Boot 应用)。
      4. 访问 http://localhost:8080 (根据你的代码定义端点)。

案例三:多模块项目 (Parent POM + 子模块)

  • 4.9 项目结构描述:

    复制代码
    parent-project/
    ├── pom.xml (packaging: pom)
    ├── core-module/
    │   ├── pom.xml
    │   ├── src/
    │   └── ...
    └── web-module/
        ├── pom.xml
        ├── src/
        └── ...
    • parent-project: 聚合项目,管理公共配置。
    • core-module: 核心业务逻辑模块 (打包类型 jar)。
    • web-module: Web 应用模块,依赖 core-module (打包类型 warjar)。
  • 4.10 父模块 pom.xml 完整代码 (管理依赖和插件):

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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.multimodule</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging> <!-- Must be pom for aggregation -->

    <name>Multi-Module Parent Project</name>

    <modules>
        <module>core-module</module>
        <module>web-module</module>
    </modules>

    <!-- Dependency Management: Define versions here for child modules -->
    <dependencyManagement>
        <dependencies>
            <!-- Define common dependencies -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>3.1.0</version> <!-- Version managed centrally -->
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
            <!-- Define internal module dependencies (if core-module is depended on) -->
            <dependency>
                <groupId>com.example.multimodule</groupId>
                <artifactId>core-module</artifactId>
                <version>${project.version}</version> <!-- Use project version -->
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- Plugin Management: Define common plugin configurations -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.11.0</version>
                    <configuration>
                        <source>17</source>
                        <target>17</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
  • 4.11 子模块 core-module/pom.xml 示例代码:
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">
    <modelVersion>4.0.0</modelVersion>

    <!-- Declare parent -->
    <parent>
        <groupId>com.example.multimodule</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- Path to parent pom -->
    </parent>

    <artifactId>core-module</artifactId>
    <packaging>jar</packaging>

    <name>Core Module</name>

    <dependencies>
        <!-- Dependencies managed by parent's dependencyManagement -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId> <!-- Version inherited -->
            <scope>test</scope>
        </dependency>
        <!-- Other core dependencies ... -->
    </dependencies>
</project>
  • 4.11 子模块 web-module/pom.xml 示例代码:
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">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.example.multimodule</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>web-module</artifactId>
    <packaging>war</packaging> <!-- Or jar if using embedded container -->

    <name>Web Module</name>

    <dependencies>
        <!-- Depend on our own core module. Version managed by parent's dependencyManagement -->
        <dependency>
            <groupId>com.example.multimodule</groupId>
            <artifactId>core-module</artifactId>
        </dependency>
        <!-- Spring Boot Web Starter (version managed by parent) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Boot Test Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Use plugin defined in parent's pluginManagement -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 4.12 核心配置点解析 :
    • 父 POM (parent-project/pom.xml) :
      • <packaging>pom</packaging>: 声明为聚合模块。
      • <modules>: 列出子模块 core-moduleweb-module
      • <dependencyManagement>: 集中管理公共依赖 (spring-boot-starter-web, junit) 和内部模块依赖 (core-module) 的版本。子模块声明依赖时无需指定 <version>
      • <pluginManagement>: 集中管理公共插件 (spring-boot-maven-plugin, maven-compiler-plugin) 的版本和配置。子模块可以直接引用这些插件。
      • <properties>: 定义公共属性。
    • 子模块 POM (core-module/pom.xml, web-module/pom.xml) :
      • <parent>: 指向父项目,继承其配置。<relativePath> 指定父 pom.xml 的位置 (通常是 ../pom.xml)。
      • <artifactId>: 定义子模块自身的标识符。
      • <packaging>: 定义子模块的输出类型 (jar, war)。
      • <dependencies>: 声明模块所需的依赖。对于父 <dependencyManagement> 中定义过的依赖,只需 <groupId><artifactId>web-module 依赖 core-module
      • <build>: 如果需要使用父 <pluginManagement> 中定义的插件,只需声明 <groupId><artifactId> (版本和配置已继承)。可以添加模块特有的插件或覆盖配置。
  • 4.13 如何构建整个项目 :
    • 命令行 :

      1. 进入 parent-project 目录 (包含父 pom.xml)。
      2. 执行命令: mvn clean install
      • Maven 会按顺序构建所有子模块 (core-module 先于 web-module,因为 web-module 依赖 core-module)。
      • 每个子模块的构建结果 (JAR/WAR) 会被安装到本地仓库 (mvn install 阶段),供其他模块或项目使用。
      • 父项目本身没有代码输出。
    • IDE :

      1. 导入 parent-project (包含父 pom.xml 的目录)。
      2. IDE 会自动识别为多模块项目,并加载所有子模块。
      3. 在父项目上右键执行 Maven 命令 (如 clean install) 会作用于所有子模块。
      4. 可以单独在子模块上执行命令。

5. 常见问题解答 (FAQ)

  • 5.1 如何解决依赖冲突?

    • 使用 mvn dependency:tree 查看完整的依赖关系树,找出冲突的库及其不同版本。
    • 分析哪个版本是需要的。通常选择更高版本,但需注意兼容性。
    • 解决方法:
      • 排除传递依赖 : 在引入冲突库的依赖声明中,使用 <exclusions> 排除掉不需要的传递依赖版本。
      • 直接声明依赖 : 在你的 <dependencies> 中显式声明你想要的依赖版本。Maven 会优先使用项目直接声明的版本 (称为"最近定义原则")。
      • 使用 <dependencyManagement>: 在父 POM 或 BOM 中强制指定依赖版本。
  • 5.2 如何覆盖父 POM 中的配置?

    • 在子模块的 pom.xml 中,直接重新定义你想覆盖的元素即可。
    • 例如,父 POM 定义了 Java 版本为 11 (<java.version>11</java.version>),子模块可以定义 <java.version>17</java.version> 来覆盖。
    • 对于插件配置,在子模块的 <plugin> 声明中,重新定义 <configuration> 即可覆盖父 POM <pluginManagement> 中的配置。
  • 5.3 如何查看项目的完整依赖树?

    • 命令行: mvn dependency:tree
    • 这个命令会打印出项目所有依赖及其传递依赖的层次结构,是分析依赖冲突的利器。
    • 可以添加 -Dverbose 查看更多细节。
  • 5.4 如何跳过测试 (mvn install -DskipTests)?

    • 命令行: mvn clean install -DskipTests
    • 这会跳过测试的编译执行阶段。
    • 如果只想跳过测试执行,但仍编译测试代码,使用 -DskipTests 的变种 -Dmaven.test.skip=true (通常效果相同) 或更精确的 -DskipITs (跳过集成测试,如果配置了的话)。最佳实践是使用 -DskipTests
  • 5.5 pom.xml 中的变量 (${...}) 是如何解析的?

    • 变量可以引用:
      • 项目属性 : 如 ${project.version}, ${project.artifactId}, ${project.basedir} (项目根目录)。所有定义在 <properties> 中的属性。所有定义在父 POM 中的属性。
      • 环境变量 : 如 ${env.JAVA_HOME}
      • Settings 属性 : 来自 settings.xml 的属性 (如 ${settings.localRepository})。
      • 系统属性 : Java 系统属性 (如 ${user.home}),也可以通过命令行 -Dproperty=value 设置。
    • 解析顺序:通常是本地属性 -> 项目属性 -> 父项目属性 -> 系统/环境/settings 属性 -> POM 元素 (如 project.version)。具体规则可能略有不同。
相关推荐
钟智强6 小时前
React2Shell:CVE-2025-66478 Next.js 远程执行漏洞深度分析与代码剖析
开发语言·javascript·ecmascript
数研小生6 小时前
Python自然语言处理:NLTK与Gensim库
开发语言·python·自然语言处理
第七序章6 小时前
【Linux学习笔记】初识Linux —— 理解gcc编译器
linux·运维·服务器·开发语言·人工智能·笔记·学习
代码栈上的思考6 小时前
SpringBoot 拦截器
java·spring boot·spring
消失的旧时光-19436 小时前
C++ 拷贝构造、拷贝赋值、移动构造、移动赋值 —— 四大对象语义完全梳理
开发语言·c++
送秋三十五6 小时前
一次大文件处理性能优化实录————Java 优化过程
java·开发语言·性能优化
雨中飘荡的记忆6 小时前
千万级数据秒级对账!银行日终批处理对账系统从理论到实战
java
jbtianci6 小时前
Spring Boot管理用户数据
java·spring boot·后端
Sylvia-girl6 小时前
线程池~~
java·开发语言