Maven 核心知识整理

一、Maven 介绍

1. 什么是 Maven?

Maven 是一个由 Apache 开源组织提供的项目构建与依赖管理工具。其核心功能可以概括为两点:

  • 依赖管理 (Dependency Management) :对项目所依赖的第三方 jar包进行统一、规范的管理,自动解决依赖传递和版本冲突问题,实现"一键构建"。

  • 项目管理 (Project Management) :提供了一套标准化的项目结构(约定优于配置)和一整套清晰的生命周期,用于完成项目的清理、编译、测试、打包、部署等构建过程。

2. Maven 的核心概念

  1. 仓库 (Repository)

    Maven 通过三种仓库来管理 jar包,形成一个高效的供应链:

    • 本地仓库 (Local Repository) :位于开发者个人电脑上(默认路径:~/.m2/repository),用于缓存从远程仓库下载的构件。

    • 中央仓库 (Central Repository):由 Maven 社区维护的全球性远程仓库,包含了绝大多数开源项目的构件。访问速度可能较慢。

    • 私服 (Private Repository):架设在公司内部的远程仓库,作为中央仓库的镜像和缓存。优点:速度快、安全、可部署内部构件。

  2. 坐标 (Coordinates)

    坐标是 Maven 用来唯一标识一个构件(jar/war 等) ​ 的定位地址,由三个基本元素组成,类似于数学中的三维坐标 (x, y, z)

    • groupId: 定义项目所属的组织或公司(反写的公司域名 + 项目名)。例如:org.apachecom.hgxy

    • artifactId: 定义当前项目(模块)的名称。

    • version: 定义当前项目的版本号。

      <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency>

二、Maven 安装与配置

1. 下载与安装

  1. 访问 Apache Maven 官网下载最新版。

  2. 将压缩包解压到一个无中文、无空格的路径 下,例如:D:\apache-maven-3.8.6

2. 配置阿里云镜像仓库(加速下载)

为了提升依赖下载速度,需要修改 Maven 安装目录下 conf/settings.xml文件。

  1. 找到 <mirrors>标签。

  2. 在其中添加阿里云镜像配置:

    <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>

3. 配置本地仓库路径(可选但推荐)

默认的本地仓库路径在用户目录下的 .m2文件夹。可以自定义到一个更大的磁盘分区。

settings.xml中找到被注释的 <localRepository>标签,取消注释并修改:

复制代码
<localRepository>D:\mvn_repository</localRepository> <!-- 自定义的本地仓库路径 -->

4. 配置环境变量(可选,方便命令行使用)

  • 新建系统变量 MAVEN_HOME,值为 Maven 的安装路径,如:D:\apache-maven-3.8.6

  • Path变量中追加:%MAVEN_HOME%\bin

  • 验证:打开命令行,输入 mvn -v,看到版本信息即表示成功。


三、IDEA 集成 Maven

1. 全局配置(推荐)

在 IDEA 中一次配置,所有新建项目都会生效。

  • 路径File-> Settings-> Build, Execution, Deployment-> Build Tools-> Maven

  • 关键配置

    • Maven home path: 指向你的 Maven 安装目录。

    • User settings file: 指向你修改过的 settings.xml文件(确保已配置阿里云镜像)。

    • Local repository: 此处会自动读取上一步配置的本地仓库路径。

2. Maven 项目标准目录结构

创建 Maven 项目后,会自动生成以下约定俗成的目录结构:

复制代码
your-project
├── src
│   ├── main
│   │   ├── java         # 存放项目的 Java 源代码
│   │   └── resources    # 存放项目的主配置文件(如:mybatis-config.xml, spring.xml)
│   └── test
│       ├── java         # 存放项目的测试代码(如:Junit 测试)
│       └── resources    # 存放测试相关的配置文件
├── target               # 项目构建输出目录(编译后的 class 文件,打包的 jar/war 等)
└── pom.xml             # Maven 项目的核心配置文件

3. 添加与下载依赖

在项目的 pom.xml文件的 <dependencies>标签内,添加所需的依赖坐标。IDEA 会自动从远程仓库下载依赖到本地仓库。

4. 解决依赖下载失败问题

下载过程中若网络中断,会生成以 .lastUpdated结尾的文件,导致后续无法继续下载。

  • 解决方案

    1. 删除本地仓库中对应依赖文件夹下的所有 .lastUpdated文件。

    2. 或者在 IDEA 中执行 Maven面板的 Reload project按钮,强制重新下载。


四、Maven 生命周期

Maven 的生命周期 (Lifecycle) 由一系列有序的阶段 (Phase) 组成,执行后面的阶段会自动执行前面所有的阶段。

  • 清理周期 (clean)mvn clean

    • 删除 target目录,清理上次构建的结果。
  • 默认周期/构建周期 (default):最核心的生命周期。

    • compile: 编译主程序的源码。

    • test: 使用单元测试框架(如 JUnit)运行测试。

    • package: 将编译后的代码打包成指定格式(jar/war)。

    • install: 将打好的包安装到本地仓库,供其他本地项目依赖。

    • deploy: 将最终的包复制到远程仓库(私服),供其他开发者或项目共享。

  • 站点周期 (site)mvn site

    • 生成项目的站点文档。

五、依赖冲突与解决方案

当项目引入的多个依赖,间接引入了同一个 jar包的不同版本时,就会产生依赖冲突。Maven 有内置的调解原则,但我们也需掌握手动解决方案。

Maven 内置调解原则:

  1. 路径近者优先原则:依赖传递路径短的版本优先。直接依赖 > 间接依赖。

  2. 第一声明者优先原则 :在 pom.xml中,同层级的依赖声明,谁声明在前,谁的版本就被采用。

手动解决方案:

  1. 排除依赖 (Exclusion)

    不想要某个依赖传递进来的特定版本,可以将其排除。

    复制代码
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.8.RELEASE</version>
        <exclusions>
            <exclusion>
                <!-- 排除 spring-context 所依赖的 spring-core 5.1.8 -->
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  2. 版本锁定 (Dependency Management)

    在父工程或当前工程的 <dependencyManagement>标签中,统一声明依赖的版本。这是最推荐、最常用的方式。

    复制代码
    <properties>
        <!-- 定义版本号属性,便于统一管理 -->
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version> <!-- 引用上面定义的属性 -->
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <!-- 在 dependencies 中引用时,无需再写版本号 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId> <!-- 版本被锁定为 5.2.0 -->
        </dependency>
    </dependencies>

六、依赖作用域 (Scope)

<scope>标签用于控制依赖在编译、测试、运行、打包等不同阶段的有效性。

Scope 对主代码(classpath)有效 对测试代码有效 会打包发布 典型示例
compile Spring-Core
test JUnit
runtime MySQL 驱动
provided Servlet-API, Tomcat

七、聚合与继承(多模块项目)

在大型项目中,通常会将一个项目拆分为多个模块(如:dao, service, web)进行开发。Maven 的聚合与继承特性完美支持此模式。

1. 概念与关系

  • 聚合 (Aggregation) :一个父模块 (通常打包方式为 pom)通过 <modules>将多个子模块组织在一起。对父模块执行 Maven 命令,会传递到所有子模块。

  • 继承 (Inheritance) :子模块通过 <parent>标签继承父模块的 pom.xml配置,从而统一管理依赖版本、插件等。

2. 标准项目结构

复制代码
maven-parent (父工程,pom)
├── maven-dao (子模块,jar)
├── maven-service (子模块,jar,依赖 maven-dao)
└── maven-web (子模块,war,依赖 maven-service)

3. 关键配置示例

  • 父工程 (maven-parent) 的 pom.xml

    复制代码
    <groupId>com.hg</groupId>
    <artifactId>maven-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging> <!-- 打包方式必须为 pom -->
    
    <!-- 聚合:声明所有子模块 -->
    <modules>
        <module>maven-dao</module>
        <module>maven-service</module>
        <module>maven-web</module>
    </modules>
    
    <!-- 继承:在 dependencyManagement 中统一管理依赖版本 -->
    <dependencyManagement>
        <dependencies>
            <!-- 这里声明所有公共依赖及其版本 -->
        </dependencies>
    </dependencyManagement>
  • 子模块 (maven-service) 的 pom.xml

    复制代码
    <!-- 继承父工程 -->
    <parent>
        <groupId>com.hg</groupId>
        <artifactId>maven-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>maven-service</artifactId>
    <packaging>jar</packaging>
    
    <dependencies>
        <!-- 依赖另一个子模块 maven-dao -->
        <dependency>
            <groupId>com.hg</groupId>
            <artifactId>maven-dao</artifactId>
            <version>${project.version}</version> <!-- 版本与父工程一致 -->
        </dependency>
        <!-- 其他依赖无需再写版本号(如果在父工程dependencyManagement中已声明)-->
    </dependencies>
相关推荐
ekkcole2 小时前
easyexcel2.2.10版本对本地文件指定行或多行样式处理
java·easyexcel
小七mod2 小时前
【Nacos】Nacos1.4.x服务注册源码分析
java·spring cloud·微服务·nacos·源码·集群·注册中心
于先生吖2 小时前
Java 打车小程序 APP 源码 顺风车滴滴跑腿系统完整实现
java·开发语言·打车系统
凌冰_2 小时前
IDEA2025 基于 Jakarta EE 开发 Servlet + Thymeleaf
java·servlet
会员源码网2 小时前
可变参数与数组混用导致的方法调用异常
java
xiaoye37082 小时前
Spring Bean 生命周期自定义扩展示例
java·spring boot·spring
sanyii3131312 小时前
k8s工作负载-ReplicaSet控制器
java·git·kubernetes
会员源码网2 小时前
泛型通配符误用导致的类型转换致命异常
java
冬夜戏雪2 小时前
【学习日记】
java·开发语言·数据库