Maven 全网最细学习手册(上篇)

🚀 Maven 全网最细学习手册(上篇)

💡 基础到进阶:掌握Maven核心概念、POM配置、生命周期与插件,为企业级开发打下坚实基础!

📖 学习导航

  • 🎯 适合人群:Java开发初学者、想深入学习Maven的开发者
  • ⏱️ 学习时长:建议3-4天完成上篇内容
  • 🎓 学习目标:掌握Maven核心概念、熟练配置POM文件、理解生命周期和插件机制
  • 📚 学习方式:理论+实践,每个知识点都有详细示例

📚 系列文章导航

  • 📖 上篇:基础概念 + POM配置 + 生命周期与插件
  • 📖 下篇:高级应用 + 多模块项目 + 实战案例 + 最佳实践

📌 第一阶段:Maven 基础概念与环境搭建

🎯 1. Maven 是什么?深度解析

1.1 Maven 的核心作用

Maven(意为"专家"、"内行")是Apache软件基金会的一个项目管理和构建自动化工具,主要用于Java项目。

🔧 三大核心功能:

  1. 依赖管理:自动下载和管理项目所需的第三方库
  2. 项目构建:编译、测试、打包、部署的自动化流程
  3. 项目标准化:统一的项目结构和构建流程
1.2 Maven vs. 其他构建工具对比
特性 Maven Ant Gradle
配置方式 XML声明式 XML过程式 Groovy/Kotlin DSL
依赖管理 ✅ 内置强大 ❌ 需要手动 ✅ 内置强大
学习曲线 中等 简单 较陡
构建速度 中等 最快
生态系统 最成熟 较少 快速发展
企业采用 最广泛 逐渐减少 快速增长
1.3 Maven 的核心思想

🎯 约定优于配置(Convention over Configuration)

  • 标准化的目录结构
  • 预定义的构建生命周期
  • 默认的插件配置
  • 统一的依赖管理方式

💡 好处:

  • 减少配置工作量
  • 提高项目的可维护性
  • 团队协作更加高效
  • 降低学习成本

🛠️ 2. Maven 安装与配置详解

2.1 下载和安装 Maven

📥 下载步骤:

  1. 访问官网:maven.apache.org/download.cg...
  2. 选择最新稳定版本(推荐3.8.x或3.9.x)
  3. 下载二进制包:apache-maven-3.9.5-bin.zip

💻 Windows 安装:

bash 复制代码
# 1. 解压到指定目录(建议无中文路径)
C:\Program Files\Apache\maven\apache-maven-3.9.5

# 2. 配置环境变量
MAVEN_HOME = C:\Program Files\Apache\maven\apache-maven-3.9.5
PATH = %PATH%;%MAVEN_HOME%\bin

# 3. 验证安装
mvn -version

🐧 Linux/Mac 安装:

bash 复制代码
# 1. 解压
tar -xzf apache-maven-3.9.5-bin.tar.gz
sudo mv apache-maven-3.9.5 /opt/maven

# 2. 配置环境变量(~/.bashrc 或 ~/.zshrc)
export MAVEN_HOME=/opt/maven
export PATH=$PATH:$MAVEN_HOME/bin

# 3. 重新加载配置
source ~/.bashrc

# 4. 验证安装
mvn -version

✅ 安装成功标志:

yaml 复制代码
Apache Maven 3.9.5 (57804ffe001d7215b5e7bcb531cf83df38f93546)
Maven home: /opt/maven
Java version: 11.0.16, vendor: Eclipse Adoptium
Java home: /usr/lib/jvm/temurin-11-jdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-74-generic", arch: "amd64", family: "unix"
2.2 配置 Maven 本地仓库

📁 默认仓库位置:

  • Windows: C:\Users\{用户名}\.m2\repository
  • Linux/Mac: ~/.m2/repository

🔧 自定义仓库位置(settings.xml):

步骤1:找到settings.xml文件

bash 复制代码
# Maven安装目录下的全局配置
{MAVEN_HOME}/conf/settings.xml

# 用户目录下的个人配置(优先级更高)
~/.m2/settings.xml

步骤2:配置本地仓库(详细配置说明)

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
          http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <!-- ==================== 本地仓库配置 ==================== -->
  <!-- 本地仓库路径:存储下载的依赖和插件 -->
  <localRepository>D:\maven\repository</localRepository>
  <!--
  说明:
  - Windows默认:C:\Users\{用户名}\.m2\repository
  - Linux/Mac默认:~/.m2/repository
  - 建议:使用SSD硬盘路径,提升构建速度
  - 注意:路径不要包含中文和空格
  -->

  <!-- 离线模式:true时只使用本地仓库 -->
  <offline>false</offline>
  <!--
  使用场景:
  - 网络不稳定时设置为true
  - 确保构建的可重复性
  - 生产环境部署时使用
  -->

  <!-- ==================== 插件组配置 ==================== -->
  <!-- 插件组:简化插件调用,无需指定完整groupId -->
  <pluginGroups>
    <pluginGroup>org.apache.maven.plugins</pluginGroup>
    <pluginGroup>org.codehaus.mojo</pluginGroup>
    <pluginGroup>org.springframework.boot</pluginGroup>
  </pluginGroups>
  <!--
  作用:可以直接使用 mvn spring-boot:run 而不是完整的
  mvn org.springframework.boot:spring-boot-maven-plugin:run
  -->

  <!-- ==================== 代理配置 ==================== -->
  <!-- 网络代理配置(企业环境常用) -->
  <proxies>
    <proxy>
      <id>company-proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.company.com</host>
      <port>8080</port>
      <username>proxy_user</username>
      <password>proxy_password</password>
      <!-- 不使用代理的主机 -->
      <nonProxyHosts>localhost|127.0.0.1|*.company.com</nonProxyHosts>
    </proxy>
  </proxies>

  <!-- ==================== 服务器认证配置 ==================== -->
  <!-- 私有仓库认证信息 -->
  <servers>
    <server>
      <id>company-nexus</id>
      <username>${env.NEXUS_USERNAME}</username>
      <password>${env.NEXUS_PASSWORD}</password>
    </server>

    <server>
      <id>company-snapshots</id>
      <username>${env.NEXUS_USERNAME}</username>
      <!-- 加密密码 -->
      <password>{COQLCE6DU6GtcS5P=}</password>
    </server>

    <!-- 部署服务器配置 -->
    <server>
      <id>deployment-server</id>
      <username>deploy_user</username>
      <password>deploy_password</password>
      <!-- 私钥文件路径(用于SCP部署) -->
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>key_passphrase</passphrase>
    </server>
  </servers>

  <!-- ==================== 镜像配置详解 ==================== -->
  <mirrors>
    <!-- 阿里云镜像(推荐:国内访问速度快) -->
    <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>central</mirrorOf>
      <name>阿里云Maven中央仓库</name>
      <url>https://maven.aliyun.com/repository/central</url>
    </mirror>

    <!-- 华为云镜像 -->
    <mirror>
      <id>huaweicloud</id>
      <mirrorOf>central</mirrorOf>
      <name>华为云Maven镜像</name>
      <url>https://repo.huaweicloud.com/repository/maven/</url>
    </mirror>

    <!-- 企业内部镜像 -->
    <mirror>
      <id>company-mirror</id>
      <!-- 镜像所有仓库,但排除公司内部仓库 -->
      <mirrorOf>*,!company-nexus,!company-snapshots</mirrorOf>
      <name>公司Maven镜像</name>
      <url>https://nexus.company.com/repository/maven-public/</url>
    </mirror>
  </mirrors>

  <!-- ==================== Profile配置详解 ==================== -->
  <profiles>
    <!-- JDK 11配置 -->
    <profile>
      <id>jdk-11</id>
      <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>11</jdk>
      </activation>
      <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
        <maven.compiler.release>11</maven.compiler.release>
      </properties>
    </profile>

    <!-- 开发环境配置 -->
    <profile>
      <id>dev</id>
      <properties>
        <!-- 跳过测试 -->
        <maven.test.skip>false</maven.test.skip>
        <!-- 详细输出 -->
        <maven.compiler.verbose>true</maven.compiler.verbose>
        <!-- 显示弃用警告 -->
        <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
      </properties>
      <repositories>
        <repository>
          <id>dev-repo</id>
          <url>https://nexus.company.com/repository/maven-snapshots/</url>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
          </snapshots>
        </repository>
      </repositories>
    </profile>

    <!-- 生产环境配置 -->
    <profile>
      <id>prod</id>
      <properties>
        <!-- 跳过测试 -->
        <maven.test.skip>true</maven.test.skip>
        <!-- 优化编译 -->
        <maven.compiler.optimize>true</maven.compiler.optimize>
      </properties>
      <repositories>
        <repository>
          <id>prod-repo</id>
          <url>https://nexus.company.com/repository/maven-releases/</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
    </profile>
  </profiles>

  <!-- ==================== 激活Profile ==================== -->
  <activeProfiles>
    <activeProfile>jdk-11</activeProfile>
    <!-- 根据需要激活环境配置 -->
    <!-- <activeProfile>dev</activeProfile> -->
  </activeProfiles>
</settings>

💡 settings.xml配置实战案例

案例1:企业开发环境配置

xml 复制代码
<!-- 企业统一settings.xml模板 -->
<settings>
  <localRepository>/opt/maven/repository</localRepository>

  <!-- 企业代理 -->
  <proxies>
    <proxy>
      <id>corporate-proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.corp.com</host>
      <port>8080</port>
      <nonProxyHosts>*.corp.com|localhost</nonProxyHosts>
    </proxy>
  </proxies>

  <!-- 企业仓库认证 -->
  <servers>
    <server>
      <id>corp-nexus</id>
      <username>${env.CORP_MAVEN_USER}</username>
      <password>${env.CORP_MAVEN_PASS}</password>
    </server>
  </servers>

  <!-- 企业镜像 -->
  <mirrors>
    <mirror>
      <id>corp-mirror</id>
      <mirrorOf>*</mirrorOf>
      <url>https://nexus.corp.com/repository/maven-public/</url>
    </mirror>
  </mirrors>
</settings>

案例2:个人开发环境优化配置

xml 复制代码
<!-- 个人开发优化settings.xml -->
<settings>
  <!-- 使用SSD路径 -->
  <localRepository>/home/dev/maven-repo</localRepository>

  <!-- 国内镜像加速 -->
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <mirrorOf>central</mirrorOf>
      <url>https://maven.aliyun.com/repository/central</url>
    </mirror>
  </mirrors>

  <!-- 开发环境Profile -->
  <profiles>
    <profile>
      <id>dev-fast</id>
      <properties>
        <!-- 并行编译 -->
        <maven.compile.fork>true</maven.compile.fork>
        <!-- 跳过JavaDoc -->
        <maven.javadoc.skip>true</maven.javadoc.skip>
        <!-- 快速测试 -->
        <maven.test.failure.ignore>true</maven.test.failure.ignore>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>dev-fast</activeProfile>
  </activeProfiles>
</settings>

🚀 常用镜像配置:

xml 复制代码
<!-- 华为云镜像 -->
<mirror>
  <id>huaweicloud</id>
  <mirrorOf>*</mirrorOf>
  <url>https://repo.huaweicloud.com/repository/maven/</url>
</mirror>

<!-- 腾讯云镜像 -->
<mirror>
  <id>nexus-tencentyun</id>
  <mirrorOf>*</mirrorOf>
  <url>http://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
</mirror>

📁 3. Maven 项目结构深度解析

3.1 标准目录布局详解
bash 复制代码
my-project/                    # 项目根目录
├── src/                       # 源代码目录
│   ├── main/                  # 主要源代码
│   │   ├── java/              # Java源代码
│   │   │   └── com/example/   # 包结构
│   │   │       └── App.java   # 主类
│   │   ├── resources/         # 资源文件
│   │   │   ├── application.properties  # 配置文件
│   │   │   ├── logback.xml    # 日志配置
│   │   │   └── static/        # 静态资源
│   │   └── webapp/            # Web应用资源(仅Web项目)
│   │       ├── WEB-INF/       # Web配置
│   │       │   └── web.xml    # Web部署描述符
│   │       ├── css/           # 样式文件
│   │       ├── js/            # JavaScript文件
│   │       └── index.html     # 首页
│   └── test/                  # 测试代码
│       ├── java/              # 测试Java代码
│       │   └── com/example/   # 测试包结构
│       │       └── AppTest.java # 测试类
│       └── resources/         # 测试资源文件
│           └── test.properties # 测试配置
├── target/                    # 编译输出目录(自动生成)
│   ├── classes/               # 编译后的class文件
│   ├── test-classes/          # 测试class文件
│   ├── surefire-reports/      # 测试报告
│   └── my-project-1.0.jar     # 打包后的jar文件
├── pom.xml                    # Maven项目对象模型文件
└── README.md                  # 项目说明文档
3.2 为什么采用这种目录结构?

🎯 设计原则:

  1. 关注点分离:源码、测试、资源分别存放
  2. 约定优于配置:标准化减少配置工作
  3. 构建工具友好:IDE和构建工具都能识别
  4. 团队协作:统一结构便于团队开发

💡 各目录作用详解:

目录 作用 说明
src/main/java 主要Java源代码 业务逻辑代码
src/main/resources 主要资源文件 配置文件、静态资源等
src/main/webapp Web应用资源 仅Web项目需要
src/test/java 测试Java代码 单元测试、集成测试
src/test/resources 测试资源文件 测试配置文件
target 构建输出目录 编译、打包结果
3.3 手动创建 Maven 项目

方法1:使用Maven原型(推荐)

bash 复制代码
# 创建简单Java项目
mvn archetype:generate \
  -DgroupId=com.example \
  -DartifactId=my-app \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=false

# 创建Web项目
mvn archetype:generate \
  -DgroupId=com.example \
  -DartifactId=my-web-app \
  -DarchetypeArtifactId=maven-archetype-webapp \
  -DinteractiveMode=false

方法2:手动创建目录结构

bash 复制代码
# 创建项目根目录
mkdir my-project && cd my-project

# 创建标准目录结构
mkdir -p src/main/java/com/example
mkdir -p src/main/resources
mkdir -p src/test/java/com/example
mkdir -p src/test/resources

# 创建基本的pom.xml文件
touch pom.xml

📝 基础pom.xml模板:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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</version>
    <packaging>jar</packaging>
    
    <name>My Project</name>
    <description>A sample Maven project</description>
    
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <!-- JUnit 5 测试框架 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

📌 第二阶段:POM 文件深度解析

📋 4. pom.xml 完全详解

POM(Project Object Model)是Maven的核心,包含了项目的所有信息和配置。

4.1 GAV 坐标详解

🎯 GAV坐标是Maven项目的唯一标识符:

xml 复制代码
<!-- G: Group ID - 组织或公司的标识 -->
<groupId>com.example</groupId>

<!-- A: Artifact ID - 项目的标识 -->
<artifactId>my-project</artifactId>

<!-- V: Version - 版本号 -->
<version>1.0.0-SNAPSHOT</version>

📝 命名规范:

元素 命名规范 示例
groupId 反向域名 com.alibaba, org.apache.commons
artifactId 项目名称(小写,用连字符分隔) spring-boot, mysql-connector-java
version 语义化版本 1.0.0, 2.1.3-SNAPSHOT

🔢 版本号规范:

  • SNAPSHOT:开发版本,会自动更新
  • RELEASE:正式发布版本
  • 语义化版本主版本.次版本.修订版本
    • 主版本:不兼容的API修改
    • 次版本:向下兼容的功能性新增
    • 修订版本:向下兼容的问题修正
4.2 packaging 打包类型
xml 复制代码
<!-- 打包类型决定了项目的构建方式和输出格式 -->
<packaging>jar</packaging>

📦 常用打包类型:

类型 说明 输出文件 适用场景
jar Java归档文件(默认) .jar 普通Java项目、库项目
war Web应用归档文件 .war Web应用项目
pom 仅包含POM文件 父项目、聚合项目
ear 企业应用归档文件 .ear Java EE应用
maven-plugin Maven插件 .jar Maven插件开发
4.3 properties 属性配置详解
xml 复制代码
<properties>
    <!-- ==================== 编译器配置 ==================== -->
    <!-- Java版本配置 -->
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <!--
    说明:
    - source: 源代码兼容的Java版本
    - target: 生成字节码的Java版本
    - 建议:两者保持一致
    -->

    <!-- 编译器发布版本(Java 9+推荐) -->
    <maven.compiler.release>11</maven.compiler.release>
    <!--
    作用:替代source和target,确保API兼容性
    优势:防止使用高版本JDK编译时意外使用新API
    -->

    <!-- ==================== 编码配置 ==================== -->
    <!-- 项目源码编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 报告输出编码 -->
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <!--
    重要性:避免中文乱码问题
    影响范围:源码编译、资源文件处理、测试报告生成
    -->

    <!-- ==================== 依赖版本管理 ==================== -->
    <!-- Spring框架版本 -->
    <spring.version>5.3.21</spring.version>
    <spring-boot.version>2.7.0</spring-boot.version>
    <spring-cloud.version>2021.0.3</spring-cloud.version>

    <!-- 测试框架版本 -->
    <junit.version>5.9.2</junit.version>
    <mockito.version>4.11.0</mockito.version>
    <testcontainers.version>1.17.3</testcontainers.version>

    <!-- 数据库相关版本 -->
    <mysql.version>8.0.33</mysql.version>
    <h2.version>2.1.214</h2.version>
    <mybatis.version>3.5.10</mybatis.version>

    <!-- 工具库版本 -->
    <commons-lang3.version>3.12.0</commons-lang3.version>
    <guava.version>31.1-jre</guava.version>
    <jackson.version>2.13.3</jackson.version>

    <!-- ==================== 插件版本管理 ==================== -->
    <!-- 核心插件版本 -->
    <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
    <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
    <maven-failsafe-plugin.version>3.0.0</maven-failsafe-plugin.version>

    <!-- 打包插件版本 -->
    <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
    <maven-war-plugin.version>3.3.2</maven-war-plugin.version>
    <maven-assembly-plugin.version>3.4.2</maven-assembly-plugin.version>

    <!-- 代码质量插件版本 -->
    <jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
    <spotbugs-maven-plugin.version>4.7.1.1</spotbugs-maven-plugin.version>
    <checkstyle-maven-plugin.version>3.1.2</checkstyle-maven-plugin.version>

    <!-- ==================== 应用配置属性 ==================== -->
    <!-- 应用基本信息 -->
    <project.mainClass>com.example.Application</project.mainClass>
    <project.finalName>${project.artifactId}-${project.version}</project.finalName>

    <!-- Docker配置 -->
    <docker.image.prefix>example</docker.image.prefix>
    <docker.image.name>${docker.image.prefix}/${project.artifactId}</docker.image.name>
    <docker.image.tag>${project.version}</docker.image.tag>

    <!-- 部署配置 -->
    <deploy.server.url>https://nexus.company.com</deploy.server.url>
    <deploy.repository.releases>${deploy.server.url}/repository/maven-releases/</deploy.repository.releases>
    <deploy.repository.snapshots>${deploy.server.url}/repository/maven-snapshots/</deploy.repository.snapshots>

    <!-- ==================== 构建行为控制 ==================== -->
    <!-- 跳过测试 -->
    <maven.test.skip>false</maven.test.skip>
    <skipTests>false</skipTests>

    <!-- 跳过文档生成 -->
    <maven.javadoc.skip>false</maven.javadoc.skip>

    <!-- 并行构建 -->
    <maven.compile.fork>true</maven.compile.fork>

    <!-- ==================== 环境相关属性 ==================== -->
    <!-- 数据库配置(可被Profile覆盖) -->
    <db.driver>com.mysql.cj.jdbc.Driver</db.driver>
    <db.url>jdbc:mysql://localhost:3306/myapp</db.url>
    <db.username>root</db.username>
    <db.password>password</db.password>

    <!-- 日志级别 -->
    <log.level>INFO</log.level>
    <log.pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</log.pattern>

    <!-- ==================== 自定义属性示例 ==================== -->
    <!-- 构建时间戳 -->
    <build.timestamp>${maven.build.timestamp}</build.timestamp>
    <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>

    <!-- Git信息(需要git-commit-id-plugin) -->
    <git.commit.id.abbrev>unknown</git.commit.id.abbrev>
    <git.branch>unknown</git.branch>

    <!-- 应用版本信息 -->
    <app.version>${project.version}</app.version>
    <app.build.number>${env.BUILD_NUMBER}</app.build.number>
</properties>

<!-- 属性使用示例 -->
<!-- 在依赖中使用属性 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

<!-- 在插件配置中使用属性 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven-compiler-plugin.version}</version>
    <configuration>
        <source>${maven.compiler.source}</source>
        <target>${maven.compiler.target}</target>
    </configuration>
</plugin>

<!-- 在资源过滤中使用属性 -->
<!-- src/main/resources/application.properties -->
<!--
app.name=${project.name}
app.version=${project.version}
app.build.timestamp=${build.timestamp}
db.url=${db.url}
-->

💡 属性使用方式:

xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
4.4 dependencies 依赖管理详解
xml 复制代码
<dependencies>
    <!-- ==================== 编译时依赖(compile scope) ==================== -->
    <!-- Spring核心依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        <!-- 依赖范围:编译、测试、运行时都需要 -->
        <scope>compile</scope>
        <!-- 可选依赖:false表示必需依赖 -->
        <optional>false</optional>
        <!-- 排除传递依赖:避免日志冲突 -->
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!--
    使用场景:业务逻辑核心依赖
    传递性:会传递给依赖此项目的其他项目
    典型例子:Spring框架、工具类库
    -->

    <!-- Web开发依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
        <!-- compile scope可以省略,这是默认值 -->
    </dependency>

    <!-- JSON处理库 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <!-- 工具类库 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>${commons-lang3.version}</version>
    </dependency>

    <!-- ==================== 提供的依赖(provided scope) ==================== -->
    <!-- Servlet API:运行时由容器提供 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!--
    使用场景:编译时需要,运行时由容器提供
    典型例子:Servlet API、JSP API、JEE API
    不会打包:不会包含在最终的WAR/JAR中
    -->

    <!-- Lombok:编译时代码生成 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>

    <!-- ==================== 运行时依赖(runtime scope) ==================== -->
    <!-- 数据库驱动:运行时才需要 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
        <scope>runtime</scope>
    </dependency>
    <!--
    使用场景:编译时不需要,运行时需要
    典型例子:数据库驱动、日志实现
    传递性:会传递给依赖此项目的其他项目
    -->

    <!-- 日志实现 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.12</version>
        <scope>runtime</scope>
    </dependency>

    <!-- ==================== 测试依赖(test scope) ==================== -->
    <!-- JUnit 5测试框架 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <!--
    使用场景:仅测试时需要
    典型例子:测试框架、Mock库、测试工具
    不传递:不会传递给依赖此项目的其他项目
    -->

    <!-- Mockito Mock框架 -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>${mockito.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- Spring测试支持 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- 测试数据库 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>${h2.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- ==================== 系统依赖(system scope) ==================== -->
    <!-- 本地JAR文件(不推荐使用) -->
    <dependency>
        <groupId>com.company</groupId>
        <artifactId>proprietary-lib</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/proprietary-lib-1.0.jar</systemPath>
    </dependency>
    <!--
    注意:system scope已被弃用,不推荐使用
    替代方案:将JAR安装到本地仓库或私有仓库
    -->
</dependencies>

<!-- ==================== 依赖管理实战案例 ==================== -->

<!-- 案例1:Spring Boot Web应用依赖配置 -->
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot.version}</version>
        <!--
        Spring Boot Starter包含:
        - spring-boot-starter
        - spring-boot-starter-tomcat
        - spring-webmvc
        - jackson-databind
        等多个依赖
        -->
    </dependency>

    <!-- 数据访问 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>${spring-boot.version}</version>
    </dependency>

    <!-- 数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
        <scope>runtime</scope>
    </dependency>

    <!-- 测试支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring-boot.version}</version>
        <scope>test</scope>
        <!-- Spring Boot Test Starter排除了JUnit 4 -->
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<!-- 案例2:微服务项目依赖配置 -->
<dependencies>
    <!-- Spring Cloud -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>${spring-cloud.version}</version>
    </dependency>

    <!-- 配置中心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
        <version>${spring-cloud.version}</version>
    </dependency>

    <!-- 服务调用 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>${spring-cloud.version}</version>
    </dependency>

    <!-- 链路追踪 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
        <version>${spring-cloud.version}</version>
    </dependency>
</dependencies>
4.5 scope 依赖范围详解
范围 编译时 测试时 运行时 传递性 说明
compile 默认范围,所有阶段都需要
provided 编译和测试时需要,运行时由容器提供
runtime 运行和测试时需要,编译时不需要
test 仅测试时需要
system 类似provided,但需要显式指定jar路径
import - - - - 仅用于dependencyManagement中导入BOM

🔍 实际应用示例:

xml 复制代码
<!-- compile: 业务逻辑依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
    <!-- scope默认为compile,可以省略 -->
</dependency>

<!-- provided: Servlet API(Tomcat提供) -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

<!-- runtime: 数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
    <scope>runtime</scope>
</dependency>

<!-- test: 测试框架 -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
4.6 optional 可选依赖
xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.21</version>
    <optional>true</optional>
</dependency>

💡 可选依赖的作用:

  • 当前项目可以使用该依赖
  • 但依赖当前项目的其他项目不会自动获得该依赖
  • 需要显式声明才能使用
4.7 build 构建配置详解
xml 复制代码
<build>
    <!-- ==================== 基础构建配置 ==================== -->
    <!-- 最终构建的文件名(不包含扩展名) -->
    <finalName>my-application</finalName>
    <!--
    默认值:${project.artifactId}-${project.version}
    示例:如果artifactId=demo,version=1.0.0,则生成demo-1.0.0.jar
    自定义:可以设置为固定名称,如app.jar
    -->

    <!-- 构建输出目录(默认target) -->
    <directory>target</directory>

    <!-- 编译输出目录(默认target/classes) -->
    <outputDirectory>target/classes</outputDirectory>

    <!-- 测试编译输出目录(默认target/test-classes) -->
    <testOutputDirectory>target/test-classes</testOutputDirectory>

    <!-- ==================== 源码目录配置 ==================== -->
    <!-- 主源码目录(默认src/main/java) -->
    <sourceDirectory>src/main/java</sourceDirectory>

    <!-- 测试源码目录(默认src/test/java) -->
    <testSourceDirectory>src/test/java</testSourceDirectory>

    <!-- 脚本源码目录(可选) -->
    <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>

    <!-- ==================== 资源文件配置详解 ==================== -->
    <resources>
        <!-- 主资源配置 -->
        <resource>
            <directory>src/main/resources</directory>
            <!-- 启用资源过滤:替换${property}占位符 -->
            <filtering>true</filtering>
            <!-- 包含的文件模式 -->
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.yml</include>
                <include>**/*.yaml</include>
            </includes>
            <!-- 排除的文件模式 -->
            <excludes>
                <exclude>**/*.tmp</exclude>
                <exclude>**/*.bak</exclude>
            </excludes>
            <!-- 目标路径(可选,默认为根路径) -->
            <targetPath>config</targetPath>
        </resource>

        <!-- 静态资源配置(不进行过滤) -->
        <resource>
            <directory>src/main/webapp</directory>
            <filtering>false</filtering>
            <includes>
                <include>**/*.js</include>
                <include>**/*.css</include>
                <include>**/*.html</include>
                <include>**/*.png</include>
                <include>**/*.jpg</include>
            </includes>
        </resource>

        <!-- 环境特定资源 -->
        <resource>
            <directory>src/main/resources-${env}</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

    <!-- 测试资源配置 -->
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </testResource>
    </testResources>

    <!-- ==================== 插件配置详解 ==================== -->
    <plugins>
        <!-- 编译插件配置 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <!-- Java版本 -->
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
                <release>${maven.compiler.release}</release>

                <!-- 编码设置 -->
                <encoding>${project.build.sourceEncoding}</encoding>

                <!-- 编译参数 -->
                <compilerArgs>
                    <arg>-parameters</arg>          <!-- 保留参数名 -->
                    <arg>-Xlint:unchecked</arg>     <!-- 显示未检查警告 -->
                    <arg>-Xlint:deprecation</arg>   <!-- 显示弃用警告 -->
                </compilerArgs>

                <!-- 显示详细信息 -->
                <verbose>true</verbose>
                <showWarnings>true</showWarnings>
                <showDeprecation>true</showDeprecation>

                <!-- 注解处理器路径 -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.24</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>

        <!-- 资源插件配置 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <!-- 编码设置 -->
                <encoding>${project.build.sourceEncoding}</encoding>

                <!-- 分隔符配置 -->
                <delimiters>
                    <delimiter>@</delimiter>        <!-- 使用@property@格式 -->
                    <delimiter>${*}</delimiter>     <!-- 使用${property}格式 -->
                </delimiters>

                <!-- 使用默认分隔符 -->
                <useDefaultDelimiters>false</useDefaultDelimiters>

                <!-- 非过滤文件扩展名 -->
                <nonFilteredFileExtensions>
                    <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
                    <nonFilteredFileExtension>swf</nonFilteredFileExtension>
                </nonFilteredFileExtensions>
            </configuration>
        </plugin>

        <!-- 清理插件配置 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <!-- 额外清理目录 -->
                <filesets>
                    <fileset>
                        <directory>logs</directory>
                        <includes>
                            <include>**/*.log</include>
                        </includes>
                    </fileset>
                </filesets>
            </configuration>
        </plugin>
    </plugins>

    <!-- ==================== 插件管理 ==================== -->
    <pluginManagement>
        <plugins>
            <!-- 统一管理插件版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <!-- 全局测试配置 -->
                    <useSystemClassLoader>false</useSystemClassLoader>
                    <forkCount>1</forkCount>
                    <reuseForks>true</reuseForks>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <!-- Spring Boot全局配置 -->
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

<!-- ==================== 构建配置实战案例 ==================== -->

<!-- 案例1:Web应用构建配置 -->
<build>
    <finalName>webapp</finalName>

    <resources>
        <!-- 配置文件过滤 -->
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>application*.properties</include>
                <include>application*.yml</include>
            </includes>
        </resource>

        <!-- 静态资源不过滤 -->
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <excludes>
                <exclude>application*.properties</exclude>
                <exclude>application*.yml</exclude>
            </excludes>
        </resource>

        <!-- Web资源 -->
        <resource>
            <directory>src/main/webapp</directory>
            <targetPath>static</targetPath>
            <filtering>false</filtering>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<!-- 案例2:多环境构建配置 -->
<build>
    <resources>
        <!-- 通用资源 -->
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>env/**</exclude>
            </excludes>
        </resource>

        <!-- 环境特定资源 -->
        <resource>
            <directory>src/main/resources/env/${env}</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

    <plugins>
        <!-- 环境特定插件配置 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target>
                            <echo message="Building for environment: ${env}"/>
                            <copy file="src/main/resources/env/${env}/config.properties"
                                  tofile="target/classes/config.properties"/>
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
4.8 parent 父POM继承
xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
    <relativePath/>
</parent>

💡 继承的内容:

  • 依赖版本管理
  • 插件配置
  • 属性配置
  • 仓库配置
4.9 modules 多模块项目
xml 复制代码
<modules>
    <module>my-project-core</module>
    <module>my-project-web</module>
    <module>my-project-service</module>
</modules>

🔍 5. 依赖管理深度实践

5.1 如何查找依赖?

🌐 主要依赖搜索网站:

  1. Maven Central Repository

    • 网址:search.maven.org/
    • 特点:官方仓库,最权威
    • 使用:搜索artifact名称或groupId
  2. MVN Repository

    • 网址:mvnrepository.com/
    • 特点:界面友好,信息详细
    • 优势:显示依赖统计、版本历史
  3. Spring Initializr

    • 网址:start.spring.io/
    • 特点:Spring生态专用
    • 优势:自动生成项目结构

🔍 搜索技巧:

bash 复制代码
# 1. 按类名搜索
搜索关键词:StringUtils
结果:org.apache.commons:commons-lang3

# 2. 按功能搜索
搜索关键词:JSON parser
结果:com.fasterxml.jackson.core:jackson-core

# 3. 按厂商搜索
搜索关键词:alibaba fastjson
结果:com.alibaba:fastjson
5.2 依赖传递性机制

🔗 传递性依赖示例:

css 复制代码
项目A 依赖 项目B (1.0)
项目B 依赖 项目C (2.0)
项目B 依赖 项目D (1.5)

结果:项目A 自动获得 项目C (2.0) 和 项目D (1.5)

📊 依赖传递规则:

  1. 最短路径优先

    css 复制代码
    A → B → C → X (2.0)
    A → D → X (1.0)
    
    结果:选择 X (1.0) - 路径更短
  2. 第一声明优先

    xml 复制代码
    <!-- 在pom.xml中的声明顺序 -->
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>lib-a</artifactId> <!-- 依赖 X (1.0) -->
    </dependency>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>lib-b</artifactId> <!-- 依赖 X (2.0) -->
    </dependency>
    
    结果:选择 X (1.0) - 先声明
  3. 覆盖传递依赖

    xml 复制代码
    <!-- 显式声明覆盖传递依赖 -->
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>X</artifactId>
        <version>3.0</version> <!-- 覆盖传递的1.0或2.0版本 -->
    </dependency>
5.3 依赖冲突解决策略

🔧 查看依赖树:

bash 复制代码
# 查看完整依赖树
mvn dependency:tree

# 查看特定依赖的冲突
mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-core

# 分析依赖冲突
mvn dependency:analyze

📋 依赖树输出示例:

less 复制代码
[INFO] com.example:my-project:jar:1.0.0
[INFO] +- org.springframework:spring-core:jar:5.3.21:compile
[INFO] |  +- org.springframework:spring-jcl:jar:5.3.21:compile
[INFO] |  \- (commons-logging:commons-logging:jar:1.2:compile - omitted for conflict with 1.1.3)
[INFO] +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] \- junit:junit:jar:4.13.2:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test

🛠️ 解决冲突的方法:

方法1:使用exclusions排除冲突依赖

xml 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.21</version>
    <exclusions>
        <!-- 排除冲突的commons-logging -->
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

方法2:显式声明依赖版本

xml 复制代码
<!-- 显式声明要使用的版本 -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

方法3:使用dependencyManagement统一管理

xml 复制代码
<dependencyManagement>
    <dependencies>
        <!-- 统一版本管理 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</dependencyManagement>

📌 第三阶段:Maven 生命周期与插件

🔄 6. Maven 生命周期详解

Maven有三个内置的构建生命周期:Clean、Default和Site。

6.1 Clean 生命周期

🧹 清理项目构建产生的文件

阶段 说明
pre-clean 执行清理前需要完成的工作
clean 清理上一次构建生成的文件
post-clean 执行清理后需要完成的工作
bash 复制代码
# 清理项目
mvn clean

# 清理并编译
mvn clean compile
6.2 Default 生命周期(核心)

🏗️ 项目部署的处理

阶段 说明 常用命令
validate 验证项目是否正确且所有必须信息是可用的 -
compile 编译项目的源代码 mvn compile
test 使用合适的单元测试框架测试已编译的源代码 mvn test
package 接受已编译的代码并打包成可发布的格式 mvn package
verify 运行任何检查以验证包是否有效且达到质量标准 mvn verify
install 安装包到本地仓库,以让其它项目依赖 mvn install
deploy 将最终的包复制到远程仓库 mvn deploy

🔍 详细阶段说明:

bash 复制代码
# 1. 编译主代码
mvn compile
# 编译 src/main/java 下的Java文件到 target/classes

# 2. 编译测试代码
mvn test-compile
# 编译 src/test/java 下的测试文件到 target/test-classes

# 3. 运行测试
mvn test
# 运行单元测试,生成测试报告

# 4. 打包项目
mvn package
# 根据packaging类型打包(jar/war/ear等)

# 5. 安装到本地仓库
mvn install
# 将项目安装到本地Maven仓库

# 6. 部署到远程仓库
mvn deploy
# 将项目部署到远程Maven仓库
6.3 Site 生命周期

📄 创建项目站点文档

阶段 说明
pre-site 执行生成站点前需要完成的工作
site 生成项目的站点文档
post-site 执行生成站点后需要完成的工作
site-deploy 将生成的站点文档部署到特定的服务器
bash 复制代码
# 生成项目站点
mvn site

# 生成并部署站点
mvn site-deploy
6.4 生命周期阶段的执行顺序

⚡ 重要特性:

  • 执行某个阶段时,会自动执行该阶段之前的所有阶段
  • 不同生命周期之间相互独立
bash 复制代码
# 执行package时的完整流程
mvn package

# 实际执行顺序:
# 1. validate
# 2. initialize
# 3. generate-sources
# 4. process-sources
# 5. generate-resources
# 6. process-resources
# 7. compile
# 8. process-classes
# 9. generate-test-sources
# 10. process-test-sources
# 11. generate-test-resources
# 12. process-test-resources
# 13. test-compile
# 14. process-test-classes
# 15. test
# 16. prepare-package
# 17. package

🔌 7. Maven 插件详解

Maven的核心功能都是通过插件实现的。每个生命周期阶段都绑定了特定的插件目标。

7.1 插件的基本概念

🎯 插件目标(Plugin Goal)

  • 插件是由一个或多个目标组成的
  • 目标是插件中的一个功能单元
  • 格式:插件前缀:目标groupId:artifactId:version:goal
bash 复制代码
# 执行编译插件的compile目标
mvn compiler:compile

# 执行依赖插件的tree目标
mvn dependency:tree
7.2 常用插件详解

🔧 maven-compiler-plugin(编译插件)

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.11.0</version>
    <configuration>
        <!-- Java版本 -->
        <source>11</source>
        <target>11</target>
        <!-- 编码格式 -->
        <encoding>UTF-8</encoding>
        <!-- 编译参数 -->
        <compilerArgs>
            <arg>-parameters</arg>
            <arg>-Xlint:unchecked</arg>
        </compilerArgs>
        <!-- 是否显示详细信息 -->
        <verbose>true</verbose>
        <!-- 是否显示弃用警告 -->
        <showDeprecation>true</showDeprecation>
        <!-- 是否显示警告 -->
        <showWarnings>true</showWarnings>
    </configuration>
</plugin>

🧪 maven-surefire-plugin(测试插件)详解

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <!-- ==================== 基础测试配置 ==================== -->
        <!-- 跳过测试执行 -->
        <skipTests>false</skipTests>
        <!-- 跳过测试编译和执行 -->
        <skip>false</skip>
        <!-- 测试失败时是否忽略(不推荐) -->
        <testFailureIgnore>false</testFailureIgnore>

        <!-- ==================== 测试文件匹配 ==================== -->
        <!-- 包含的测试文件模式 -->
        <includes>
            <include>**/*Test.java</include>
            <include>**/*Tests.java</include>
            <include>**/*TestCase.java</include>
            <include>**/Test*.java</include>
        </includes>

        <!-- 排除的测试文件模式 -->
        <excludes>
            <exclude>**/*IntegrationTest.java</exclude>
            <exclude>**/*IT.java</exclude>
            <exclude>**/Abstract*.java</exclude>
        </excludes>

        <!-- ==================== 并行执行配置 ==================== -->
        <!-- 并行执行级别:methods, classes, both, suites, suitesAndClasses, suitesAndMethods, classesAndMethods, all -->
        <parallel>methods</parallel>
        <!-- 线程数配置 -->
        <threadCount>4</threadCount>
        <!-- 每个核心的线程数 -->
        <perCoreThreadCount>2</perCoreThreadCount>
        <!-- 是否使用无限线程 -->
        <useUnlimitedThreads>false</useUnlimitedThreads>

        <!-- ==================== JVM配置 ==================== -->
        <!-- JVM参数 -->
        <argLine>-Xmx1024m -XX:MaxPermSize=256m -Dfile.encoding=UTF-8</argLine>

        <!-- Fork配置:每个测试类启动新JVM -->
        <forkCount>1</forkCount>
        <reuseForks>true</reuseForks>

        <!-- ==================== 系统属性配置 ==================== -->
        <systemPropertyVariables>
            <!-- Spring配置 -->
            <spring.profiles.active>test</spring.profiles.active>
            <!-- 数据库配置 -->
            <db.url>jdbc:h2:mem:testdb</db.url>
            <db.username>sa</db.username>
            <db.password></db.password>
            <!-- 日志配置 -->
            <log.level>DEBUG</log.level>
        </systemPropertyVariables>

        <!-- 环境变量 -->
        <environmentVariables>
            <ENV>test</ENV>
            <LOG_LEVEL>DEBUG</LOG_LEVEL>
        </environmentVariables>

        <!-- ==================== 报告配置 ==================== -->
        <!-- 报告目录 -->
        <reportsDirectory>target/surefire-reports</reportsDirectory>

        <!-- 测试输出配置 -->
        <printSummary>true</printSummary>
        <redirectTestOutputToFile>false</redirectTestOutputToFile>

        <!-- ==================== 高级配置 ==================== -->
        <!-- 工作目录 -->
        <workingDirectory>target</workingDirectory>

        <!-- 类路径配置 -->
        <useSystemClassLoader>false</useSystemClassLoader>
        <useManifestOnlyJar>false</useManifestOnlyJar>

        <!-- 测试超时(秒) -->
        <forkedProcessTimeoutInSeconds>1800</forkedProcessTimeoutInSeconds>

        <!-- 测试运行器配置(JUnit 5) -->
        <properties>
            <configurationParameters>
                junit.jupiter.execution.parallel.enabled=true
                junit.jupiter.execution.parallel.mode.default=concurrent
                junit.jupiter.execution.parallel.config.strategy=dynamic
            </configurationParameters>
        </properties>
    </configuration>

    <!-- ==================== 执行配置 ==================== -->
    <executions>
        <!-- 单元测试执行 -->
        <execution>
            <id>unit-tests</id>
            <phase>test</phase>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <includes>
                    <include>**/*Test.java</include>
                </includes>
                <excludes>
                    <exclude>**/*IntegrationTest.java</exclude>
                </excludes>
            </configuration>
        </execution>
    </executions>
</plugin>

<!-- ==================== 测试插件实战案例 ==================== -->

<!-- 案例1:Spring Boot项目测试配置 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <!-- Spring Boot测试优化 -->
        <argLine>-Xmx2048m -Dspring.test.context.cache.maxSize=3</argLine>

        <systemPropertyVariables>
            <spring.profiles.active>test</spring.profiles.active>
            <spring.test.context.cache.maxSize>3</spring.test.context.cache.maxSize>
        </systemPropertyVariables>

        <!-- 测试分组 -->
        <groups>unit</groups>
        <excludedGroups>integration,slow</excludedGroups>

        <!-- 并行配置 -->
        <parallel>classes</parallel>
        <threadCount>2</threadCount>
    </configuration>
</plugin>

<!-- 案例2:大型项目测试配置 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <!-- 大项目内存配置 -->
        <argLine>-Xmx4096m -XX:MaxMetaspaceSize=512m</argLine>

        <!-- 高并发测试 -->
        <parallel>all</parallel>
        <threadCount>8</threadCount>
        <perCoreThreadCount>2</perCoreThreadCount>

        <!-- 测试稳定性配置 -->
        <rerunFailingTestsCount>2</rerunFailingTestsCount>
        <forkedProcessTimeoutInSeconds>3600</forkedProcessTimeoutInSeconds>

        <!-- 详细报告 -->
        <printSummary>true</printSummary>
        <reportFormat>xml</reportFormat>
    </configuration>
</plugin>

<!-- 案例3:CI环境测试配置 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <!-- CI环境优化 -->
        <forkCount>1C</forkCount>  <!-- 每个CPU核心一个fork -->
        <reuseForks>false</reuseForks>

        <!-- 失败快速反馈 -->
        <skipAfterFailureCount>5</skipAfterFailureCount>

        <!-- CI环境系统属性 -->
        <systemPropertyVariables>
            <spring.profiles.active>ci</spring.profiles.active>
            <testcontainers.reuse.enable>true</testcontainers.reuse.enable>
        </systemPropertyVariables>

        <!-- 报告格式 -->
        <reportFormat>xml</reportFormat>
        <useFile>true</useFile>
    </configuration>
</plugin>

📦 maven-jar-plugin(JAR打包插件)

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <!-- 归档配置 -->
        <archive>
            <!-- 清单文件配置 -->
            <manifest>
                <!-- 添加classpath -->
                <addClasspath>true</addClasspath>
                <!-- classpath前缀 -->
                <classpathPrefix>lib/</classpathPrefix>
                <!-- 主类 -->
                <mainClass>com.example.Application</mainClass>
            </manifest>
            <!-- 清单条目 -->
            <manifestEntries>
                <Built-By>Maven</Built-By>
                <Build-Jdk>${java.version}</Build-Jdk>
                <Implementation-Version>${project.version}</Implementation-Version>
            </manifestEntries>
        </archive>
        <!-- 排除文件 -->
        <excludes>
            <exclude>**/*.properties</exclude>
        </excludes>
    </configuration>
</plugin>

🌐 maven-war-plugin(WAR打包插件)

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.3.2</version>
    <configuration>
        <!-- WAR文件名 -->
        <warName>my-web-app</warName>
        <!-- 是否失败在缺少web.xml -->
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <!-- Web资源目录 -->
        <webResources>
            <resource>
                <directory>src/main/webapp</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.html</include>
                    <include>**/*.jsp</include>
                </includes>
            </resource>
        </webResources>
        <!-- 归档配置 -->
        <archive>
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>

🎁 maven-assembly-plugin(自定义打包插件)

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.4.2</version>
    <configuration>
        <!-- 描述符 -->
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <!-- 主类 -->
        <archive>
            <manifest>
                <mainClass>com.example.Application</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>
7.3 插件执行配置

⚙️ executions 执行配置

xml 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <!-- 在compile阶段执行 -->
        <execution>
            <id>compile-phase-execution</id>
            <phase>compile</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <echo message="编译阶段执行自定义任务"/>
                    <mkdir dir="${project.build.directory}/custom"/>
                </target>
            </configuration>
        </execution>

        <!-- 在package阶段执行 -->
        <execution>
            <id>package-phase-execution</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <echo message="打包阶段执行自定义任务"/>
                    <copy todir="${project.build.directory}/custom">
                        <fileset dir="${project.build.directory}/classes"/>
                    </copy>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

📚 上篇总结与下篇预告

🎯 上篇学习成果检验

通过上篇的学习,您应该掌握:

✅ 基础概念

  • Maven的核心作用和设计思想
  • 标准项目结构和目录布局
  • 环境安装和配置优化

✅ POM文件配置

  • GAV坐标系统和命名规范
  • 依赖管理和scope范围
  • 属性配置和构建设置
  • 依赖冲突的识别和解决

✅ 生命周期与插件

  • 三大生命周期的阶段和作用
  • 常用插件的配置和使用
  • 插件执行的绑定和配置

🚀 下篇内容预告

在下篇中,我们将深入探讨:

📌 第四阶段:高级应用

  • 🏗️ 多模块项目管理:父子POM配置、模块依赖、构建策略
  • 🎛️ Profile配置管理:多环境配置、条件激活、属性覆盖
  • 📦 仓库管理:本地/远程仓库、镜像配置、部署策略

📌 第五阶段:实战案例与最佳实践

  • 🎯 Spring Boot项目实战:完整项目配置、Docker集成
  • 常用命令大全:依赖管理、插件操作、高级选项
  • 🔧 故障排除指南:常见问题诊断、调试技巧、性能优化
  • 🏆 最佳实践:项目结构规范、版本管理、构建优化

📚 继续学习:建议先通过实际项目练习上篇内容,熟悉Maven的基础操作后,再继续学习下篇的高级应用和实战案例。


💡 学习建议:上篇内容是Maven学习的基础,建议通过创建实际项目来练习POM配置、依赖管理和插件使用,为学习下篇的高级内容做好准备。

相关推荐
一根会骑马的Banana10 分钟前
关于DTO、DO、BO、VO
java
cur1es14 分钟前
数据结构Java--8
java·数据结构·算法·散列表
简单点了1 小时前
SM4加密算法
java·开发语言
用户3721574261352 小时前
Java 实现HTML转Word:从HTML文件与字符串到可编辑Word文档
java
yvya_2 小时前
Mybatis总结
java·spring·mybatis
姜太小白2 小时前
【VSCode】VSCode为Java C/S项目添加图形用户界面
java·c语言·vscode
一路向北North2 小时前
java将doc文件转pdf
java·pdf
咕白m6252 小时前
Java 开发:用 Spire.PDF 高效压缩 PDF 文件
java·编程语言
万行3 小时前
点评项目(Redis中间件)&第一部分Redis基础
java·数据库·redis·缓存·中间件
用户2707912938183 小时前
异常处理!Exception 和 Error 有什么区别?
java