Maven进阶

Maven进阶

Maven 是一个 项目管理工具,主要解决三件事:

  • 依赖管理
  • 项目构建
  • 项目信息管理

帮 Java 项目统一"怎么下依赖、怎么编译、怎么测试、怎么打包、怎么发布"的工具。

约定大于配置

Maven 非常强调这个思想。

比如它约定:

  • 主代码放 src/main/java
  • 资源文件放 src/main/resources
  • 测试代码放 src/test/java
  • 测试资源放 src/test/resources
  • 打包输出到 target

所以你只要按规范来,很多配置根本不用写。

这就是为什么 Maven 项目结构几乎长得都一样。

依赖坐标唯一标识

Maven 里的一个 jar,不是靠文件名识别,而是靠一组坐标:

  • groupId
  • artifactId
  • version

例如:

复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.30</version>
</dependency>

这三个东西共同确定一个依赖。

面试里经常问:
Maven 如何唯一确定一个构件?

答案就是:
GAV 坐标:groupId + artifactId + version

Maven 的安装与目录结构

Maven 本身是 Java 写的,所以运行 Maven 需要 JDK。

一般先配:

  • JAVA_HOME
  • MAVEN_HOME
  • PATH

验证命令:

复制代码
mvn -v
  • bin:启动脚本
  • conf:全局配置文件,比如 settings.xml
  • lib:Maven 自己依赖的 jar

Maven 项目的标准目录结构

java 复制代码
project
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   ├── resources
│   │   └── webapp
│   └── test
│       ├── java
│       └── resources
└── target

pom.xml 是什么

pom 全称:

Project Object Model

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.demo</groupId>
    <artifactId>maven-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

modelVersion

POM 模型版本,通常固定 4.0.0。

groupId

组织、公司、团队、项目域名反写。

比如:

复制代码
<groupId>com.company.project</groupId>

artifactId

模块名、项目名。

比如:

复制代码
<artifactId>user-service</artifactId>

version

当前项目版本。

例如:

  • 1.0.0
  • 1.0-SNAPSHOT

packaging

表示打包方式。

常见值:

  • jar
  • war
  • pom

例子:

复制代码
<packaging>jar</packaging>

jar、war、pom 区别?

  • jar:普通 Java 项目
  • war:Web 项目
  • pom:父工程/聚合工程,不直接放业务代码打包运行

依赖管理 dependencies

基本写法

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.30</version>
    </dependency>
</dependencies>

依赖就是:

当前项目在编译、测试、运行过程中需要用到的外部构件。

依赖的关键属性

属性名 是否必须 作用 说明/特点 面试关键点
groupId ✅ 标识组织/公司 类似包名(反域名) GAV 三要素之一
artifactId ✅ 标识模块/项目 jar 名(不含版本) 在 group 内唯一
version ✅ 指定版本 SNAPSHOT / RELEASE GAV 唯一定位
scope ❌ 控制依赖生效范围 compile/test/provided/runtime 控制 classpath
optional ❌ 是否可选依赖 true 时不向下传递 阻断依赖传递
exclusions ❌ 排除传递依赖 精确移除某个依赖 解决冲突常用
type ❌ 指定依赖类型 默认 jar 可为 war、pom 等
classifier ❌ 构件分类标识 如 sources、javadoc 区分同一构件变体
systemPath ❌ 本地依赖路径 配合 system scope 使用 ⚠️不推荐
optional(传递影响) ❌ 控制传递行为,自己用 不会传递给依赖方 面试加分点

依赖作用域 scope

scope 编译(main) 测试(test) 运行(runtime) 是否打包 典型场景
compile(默认) ✅ ✅ ✅ ✅ Spring、工具类
test ❌ ✅ ❌ ❌ JUnit、Mockito
provided ✅ ✅ ❌ ❌ Servlet API(容器提供)
runtime ❌ ❌ ✅ ✅ JDBC 驱动
scope 什么时候用
compile 全流程都需要 业务核心依赖
test 只在测试用 单元测试
provided 编译需要,运行环境提供 Web 容器依赖
runtime 编译不需要,运行需要 数据库驱动

依赖传递

如果你依赖 A,而 A 又依赖 B,那么通常你也会自动得到 B。

这就叫:

Transitive Dependency,传递依赖。

看依赖树

复制代码
mvn dependency:tree

依赖冲突

冲突怎么来的,比如

复制代码
项目 -> A -> B 1.0
项目 -> C -> B 2.0

Maven 的冲突解决策略

第一条:最近优先

谁离当前项目更近,优先用谁。

例如:

复制代码
项目 -> A -> B 1.0
项目 -> B 2.0

最终一般选 B 2.0,因为直接依赖路径更短。


第二条:路径相同,先声明优先

如果路径长度相同,谁先写在 POM 里,谁优先。

怎么解决冲突

常见手段:

  • 显式指定版本
  • 使用 dependencyManagement
  • 使用 exclusions 排除不想要的依赖
  • 用 dependency:tree 分析来源

仓库机制

本地仓库

默认在用户目录下:

复制代码
~/.m2/repository

作用:

  • 缓存下载过的依赖
  • 避免每次联网下载
  • 支持安装自己构建的 jar

中央仓库

Maven 官方默认远程仓库。

如果本地没有依赖,就去远程仓库下载。


私服

公司内部一般会搭私服,比如 Nexus、Artifactory。

作用:

  • 缓存外部依赖
  • 存储公司内部 jar
  • 控制依赖下载来源
  • 提高下载速度和安全性

生命周期

validate

检查项目是否正确,配置是否完整。

compile

编译主代码。

test

执行测试。

package

打包,生成 jar/war。

install

安装到本地仓库。

deploy

发布到远程仓库。

相关推荐
默_笙3 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
qq_426003963 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技3 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时3 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
奇思妙想聪明勤奋的小羊3 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
lpfasd1233 天前
2026年第38周GitHub趋势周报
python·科技·github
IZero073 天前
Jev 与 Laya
python·语言模型