【工具】如何认识Maven

如何认识Maven

一、我的Maven探索:

Maven是什么?

Maven 是 Apache 软件基金会开发的一款项目管理与综合构建工具。它统一管理项目的依赖、构建、打包、发布等全生命周期,核心思想是 "约定优于配置"(Convention over Configuration)。

从三个视角可以更清晰地理解 Maven:

  1. Maven 是一个包依赖管理工具
  2. Maven 是一个自动构建工具
  3. Maven 是一个约定目录结构的项目

    提问:
    1. Maven是一款项目管理与综合构建工具。项目管理包括哪些内容?Maven参与项目管理的哪些步骤?什么是综合构建?
    2. Maven出现之前/之后,项目的依赖、构建、打包、发布等生命周期各自怎么操作执行?
    3. 约定优于配置,配置是什么?约定又是什么?在Maven中哪里用到了约定优于配置?

一个包依赖管理工具。

a. 三化:

ⅰ. 系统化:包依赖管理工具还有哪些?

ⅱ. 全局化:包依赖管理工具是由什么组成的?

ⅲ. 结构化:

b. 作为一个包依赖管理工具,是怎么工作的?

ⅰ. 包依赖管理的管理包括哪些内容?

依赖包下载:这就要从pom.xml文件说起,一个pom.xml文件中写了当前项目依赖的项目,Maven解析(读取)pom.xml文件,从中获取到依赖项目的包路径/artifactid/版本号,从本地仓库/私服仓库/中央仓库 去下载下来jar包,放到项目的External Libraries。

提问:

为什么要放到这个路径下?放到这里有什么用?jar包下载下来怎么用?

jar包里是什么内容?.class二进制文件等。

依赖包版本冲突解决:

直接依赖、传递依赖,最短路径优先原则。

一个自动构建工具。

自动体现在哪里?怎么理解自动?

a. 三化:

ⅰ. 系统化:同级别的构建工具有哪些?

ⅱ. 全局化:自动构建工具由那几部分组成?

ⅲ. 结构化:

b. 作为一个自动构建工具,是怎么工作的?

Maven提供了一些.sh文件(脚本文件)?里面封装了一些命令,对项目进行生命周期的操作。

提问:

项目生命周期,包括构建、打包、发布啥的,有哪些?分别是什么意思?

一个约定目录结构的项目。

a. 三化:

ⅰ. 系统化:还有哪些约定目录结构的项目。

ⅱ. 全局化:Maven的目录结构是怎样的?

ⅲ. 结构化:

b. 作为一个约定目录结构的项目,是怎么工作的?

c. 约定目录结构有什么作用?是给谁看的?

d. Maven中的pom文件是干什么的?起什么作用?

总结:

不怕不知道,就怕不知道。

知道自己不知道,不知道自己知不知道。

二、"三化"定义

系统化是研究对象周围的事物,与研究对象平级。

全局化是研究对象内部的事物,可解构后重构成研究对象。

结构化是系统化和全局化中搞到的事物之间的关系,因果,方位,相对位置,等等。

三、AI完善润色

Maven 是什么?

Maven 是 Apache 软件基金会开发的一款项目管理与综合构建工具 。它统一管理项目的依赖、构建、打包、发布等全生命周期,核心思想是 "约定优于配置"(Convention over Configuration)

从三个视角可以更清晰地理解 Maven:

  1. Maven 是一个包依赖管理工具
  2. Maven 是一个自动构建工具
  3. Maven 是一个约定目录结构的项目

提问与解答

问题1:Maven 是一款项目管理与综合构建工具。项目管理包括哪些内容?Maven 参与项目管理的哪些步骤?什么是综合构建?

项目管理 包括:需求分析、设计、编码、测试、构建、打包、发布、部署、运维监控等全流程。Maven 主要参与其中的构建、打包、发布、依赖管理环节,不参与需求分析、UI设计、编码等开发阶段。

综合构建 中的"综合"体现在:Maven 不仅仅是编译工具,它将编译、测试、打包、依赖管理、文档生成、代码质量检查等多种任务整合在一个统一的工具和流程中,通过一套标准化的生命周期和插件体系完成。

问题2:Maven 出现之前/之后,项目的依赖、构建、打包、发布等生命周期各自怎么操作执行?

阶段 Maven 出现之前 Maven 出现之后
依赖管理 手动下载 jar 包,放入项目 lib 目录;版本冲突需人工排查 在 pom.xml 中声明依赖坐标,Maven 自动下载并管理传递依赖
编译 使用 javac 命令手动编译,需手动配置 classpath mvn compile,Maven 自动处理 classpath
测试 手动运行测试类或使用 JUnit 独立运行 mvn test,自动执行测试并生成报告
打包 手动使用 jar 命令打包,需自己组织目录结构 mvn package,自动生成 JAR/WAR
发布 手动上传到服务器或仓库 mvn deploy,自动发布到远程仓库

问题3:约定优于配置,配置是什么?约定又是什么?在 Maven 中哪里用到了约定优于配置?

  • 配置:需要开发者显式声明的内容,如依赖坐标、插件参数、自定义目录结构等。
  • 约定:Maven 默认的规则,无需开发者声明即可生效,如标准目录结构、生命周期阶段顺序、默认插件绑定等。

约定优于配置的体现

约定内容 无需配置的默认行为
目录结构 源码放在 src/main/java,测试放在 src/test/java,无需声明
编译输出 自动输出到 target/classes
打包类型 默认为 jar,无需显式指定
生命周期 执行 mvn package 会自动先执行 compile、test
插件绑定 compile 阶段自动绑定 maven-compiler-plugin

一、Maven 作为"包依赖管理工具"

1.1 三化分析

系统化(与研究对象平级的周边事物):

类别 具体内容
同类型工具 npm(Node.js)、pip(Python)、go mod(Go)、Gradle(Java 生态)、yarn、pnpm
仓库服务 Maven Central(中央仓库)、Nexus(私服)、Artifactory(企业仓库)
相关标准 依赖坐标规范(GAV)、仓库协议规范、POM 规范

全局化(研究对象内部可解构的事物):

组成部分 说明
依赖解析引擎 根据 GAV 坐标解析依赖位置
仓库管理器 管理本地仓库、远程仓库的访问与缓存
依赖树构建器 构建完整的依赖树,处理传递依赖
冲突调解器 按规则解决版本冲突
核心概念 GAV 坐标、scope(依赖范围)、optional(可选依赖)、exclusions(排除依赖)

结构化(系统化与全局化中各事物之间的关系):

关系类型 具体体现
因果关系 外部仓库不可用 → 依赖下载失败;scope 配置错误 → 打包时缺少依赖
层次关系 本地仓库 → 私服仓库 → 中央仓库(优先级从高到低)
依赖关系 传递依赖机制:A 依赖 B,B 依赖 C → A 自动获得 C
冲突关系 最短路径优先、先声明优先原则解决版本冲突

1.2 作为包依赖管理工具是如何工作的?

包依赖管理的管理包括哪些内容?

  1. 依赖声明 :在 pom.xml 中通过 <dependency> 声明项目所需的外部库
  2. 依赖下载:从仓库获取依赖的 jar 包
  3. 依赖解析:处理传递依赖,构建完整的依赖树
  4. 依赖范围管理:控制依赖在不同阶段的可见性
  5. 版本冲突解决:当多个依赖引入同一库的不同版本时,按规则选择

依赖包下载流程

复制代码
pom.xml 声明依赖(GAV 坐标)
         ↓
Maven 解析 pom.xml,获取依赖信息
         ↓
检查本地仓库(~/.m2/repository)
    ├─ 存在 → 直接使用
    └─ 不存在 → 检查私服仓库
                    ├─ 存在 → 下载到本地仓库
                    └─ 不存在 → 检查中央仓库
                                    ├─ 存在 → 下载到本地仓库
                                    └─ 不存在 → 报错
         ↓
将 jar 包加入项目的 classpath(IDE 中显示为 External Libraries)

提问:为什么要放到 External Libraries 路径下?放到这里有什么用?jar 包下载下来怎么用?

  • External Libraries 是什么:这是 IDE(如 IntelliJ IDEA)的概念,不是 Maven 的概念。IDE 将 Maven 下载到本地仓库的 jar 包以"外部库"的形式展示,方便开发者查看和引用。
  • 为什么要展示:IDE 需要知道项目的 classpath,才能提供代码补全、语法检查、跳转定义等功能。External Libraries 就是 IDE 对 classpath 的可视化展示。
  • jar 包怎么用 :jar 包下载到本地仓库后,Maven 会自动将其路径加入编译时的 classpath。编译器在编译代码时,会在 classpath 中查找 import 语句引用的类。运行时,JVM 同样需要这些 jar 包在 classpath 中才能加载类。

jar 包里是什么内容?

jar(Java Archive)本质上是一个压缩文件,内部结构如下:

复制代码
my-library.jar
├── META-INF/
│   └── MANIFEST.MF          # 清单文件,包含入口类等信息
├── com/
│   └── example/
│       ├── MyClass.class    # 编译后的字节码文件
│       └── OtherClass.class
└── application.properties   # 资源文件
  • .class 文件:Java 源代码编译后的字节码,是 jar 包的核心内容
  • 资源文件:配置文件、静态资源等
  • META-INF:元数据,如清单文件、签名信息等

依赖包版本冲突解决

  • 直接依赖:项目 pom.xml 中直接声明的依赖
  • 传递依赖:直接依赖所依赖的其他库,会自动传递到当前项目

冲突解决原则

  1. 最短路径优先:A → B → C(v1.0) 和 A → D → C(v2.0),选择 v1.0(路径更短)

  2. 先声明优先:路径长度相同时,pom.xml 中先声明的依赖优先

    示例:
    项目依赖 A 和 B
    A 依赖 C(v1.0)
    B 依赖 C(v2.0)

    如果 A 在 pom.xml 中先声明,则使用 C(v1.0)


二、Maven 作为"自动构建工具"

2.1 三化分析

系统化(与研究对象平级的周边事物):

类别 具体内容
同类型工具 Ant、Gradle、Make、npm scripts、Bazel、Rake
相关标准 Java 编译规范、测试框架协议(JUnit、TestNG)
配套工具 CI/CD 系统(Jenkins、GitLab CI、GitHub Actions)、代码覆盖率工具(JaCoCo)

全局化(研究对象内部可解构的事物):

组成部分 说明
生命周期引擎 管理 clean、default、site 三大生命周期
阶段调度器 按顺序调度各阶段执行
插件管理器 加载和管理插件,绑定插件目标到阶段
构建上下文 管理构建过程中的状态和产物
核心概念 生命周期、阶段、插件、目标、配置

结构化(系统化与全局化中各事物之间的关系):

关系类型 具体体现
因果关系 执行 mvn package → 自动触发 compile、test 阶段;插件配置错误 → 对应阶段失败
时序关系 阶段按固定顺序执行:validate → compile → test → package → install → deploy
层次关系 生命周期包含阶段,阶段绑定插件目标,目标由插件实现
继承关系 父 POM 的插件配置可被子 POM 继承和覆盖

2.2 作为自动构建工具是如何工作的?

自动体现在哪里?怎么理解自动?

Maven 的"自动"体现在三个方面:

  1. 自动执行顺序:执行某个阶段时,前面的阶段会自动按顺序执行

    • 执行 mvn package → 自动执行 compile → test → package
    • 执行 mvn install → 自动执行 compile → test → package → install
  2. 自动绑定插件:每个阶段默认绑定了合适的插件目标

    • compile 阶段 → maven-compiler-plugin:compile
    • test 阶段 → maven-surefire-plugin:test
    • package 阶段 → maven-jar-plugin:jar
  3. 自动处理依赖:编译、测试、打包时自动将依赖加入 classpath,无需手动配置

Maven 提供了哪些脚本文件?

Maven 安装目录的 bin/ 下包含以下脚本:

脚本文件 作用
mvn(Linux/Mac) 主命令脚本,执行 Maven 构建
mvn.cmd(Windows) Windows 批处理脚本
mvnDebug 调试模式启动 Maven
m2.conf Maven 运行时配置

这些脚本封装了 Java 启动命令,核心逻辑是:

bash 复制代码
java -classpath maven-core.jar org.codehaus.plexus.classworlds.launcher.Launcher [goals]

Maven 三大生命周期

生命周期 说明 主要阶段
clean 清理项目 pre-clean → clean → post-clean
default 核心构建流程 validate → compile → test → package → verify → install → deploy
site 生成项目站点文档 pre-site → site → post-site → site-deploy

生命周期执行示例

复制代码
mvn clean package
    ↓
执行 clean 生命周期:删除 target 目录
    ↓
执行 default 生命周期:
    validate → generate-sources → process-resources
    → compile → process-classes
    → generate-test-sources → process-test-resources
    → test-compile → test
    → package
    ↓
生成 target/my-app-1.0.jar

三、Maven 作为"约定目录结构的项目"

3.1 三化分析

系统化(与研究对象平级的周边事物):

类别 具体内容
同类型项目结构 Gradle 项目、Eclipse 项目、IntelliJ IDEA 项目
相关标准 Java EE 项目结构规范、Web 应用目录规范(WAR 结构)
配套工具 IDE(IntelliJ IDEA、Eclipse、VS Code)、代码分析工具(SonarQube)

全局化(研究对象内部可解构的事物):

组成部分 说明
目录识别器 识别源码目录、测试目录、资源目录
资源处理器 处理资源文件的过滤和复制
编译路径管理器 管理源码路径和输出路径
核心概念 标准目录布局、资源过滤、打包类型

结构化(系统化与全局化中各事物之间的关系):

关系类型 具体体现
因果关系 目录结构正确 → IDE 自动识别;目录结构错误 → 编译失败
层次关系 src/main/java 为一级目录,其下按包名层级展开
方位关系 src/mainsrc/test 平级;src/main/javasrc/main/resources 平级
映射关系 src/main/resourcestarget/classessrc/test/java 仅在测试阶段编译

3.2 Maven 标准目录结构

复制代码
my-project/
├── pom.xml                          # 项目对象模型文件(核心配置)
├── src/
│   ├── main/
│   │   ├── java/                    # Java 源代码目录
│   │   │   └── com/example/app/
│   │   │       ├── App.java
│   │   │       └── service/
│   │   ├── resources/               # 主资源文件目录
│   │   │   ├── application.yml      # 配置文件
│   │   │   └── static/              # 静态资源
│   │   └── webapp/                  # Web 项目专用
│   │       └── WEB-INF/
│   │           └── web.xml
│   └── test/
│       ├── java/                    # 测试代码目录
│       │   └── com/example/app/
│       │       └── AppTest.java
│       └── resources/               # 测试资源文件目录
├── target/                          # 构建产物目录(自动生成)
│   ├── classes/                     # 编译后的 class 文件
│   ├── test-classes/                # 测试编译产物
│   └── my-app-1.0.jar               # 打包产物
└── README.md

3.3 约定目录结构有什么作用?是给谁看的?

作用 给谁看
降低配置成本:Maven 自动识别源码/测试/资源位置,无需在 pom.xml 中显式配置路径 Maven 本身(编译器、资源插件、测试插件)
提高可读性:新成员加入项目后能立刻知道代码在哪里、配置在哪里 开发人员、维护人员
IDE 智能识别:IntelliJ IDEA、Eclipse 等可一键导入并自动设置源码/测试目录 IDE、构建工具
规范化:所有 Maven 项目结构统一,便于跨团队协作与持续集成 团队、CI/CD 系统
便于自动化 :测试目录与源码目录分离,mvn test 自动找到测试类执行 Maven Surefire 插件

3.4 pom.xml 是干什么的?起什么作用?

POM(Project Object Model,项目对象模型) 是 Maven 项目的核心描述文件,它以 XML 格式描述一个项目:是什么、依赖什么、如何构建、输出什么。

核心作用

作用 说明 对应元素
项目坐标声明 定义项目在仓库中的唯一标识 <groupId><artifactId><version>
依赖管理 声明项目所需的第三方依赖 <dependencies>
版本管理 统一管理依赖版本,避免重复声明 <properties><dependencyManagement>
构建配置 配置插件、资源处理、输出目录等 <build><plugins>
项目信息 描述项目元数据 <name><description><licenses>
继承与聚合 父 POM 继承、多模块聚合 <parent><modules>
仓库配置 配置依赖下载与产物发布的仓库 <repositories><distributionManagement>

pom.xml 结构示例

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>

    <!-- 项目坐标 -->
    <groupId>com.example</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <!-- 项目信息 -->
    <name>My Application</name>
    <description>A sample Maven project</description>

    <!-- 版本属性 -->
    <properties>
        <java.version>11</java.version>
        <spring.version>2.7.0</spring.version>
    </properties>

    <!-- 依赖声明 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

    <!-- 构建配置 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

四、三个视角的总结

视角 系统化(周边平级事物) 全局化(内部可解构事物) 结构化(事物间关系)
依赖管理 npm、pip、Gradle、Maven Central、Nexus GAV 坐标、scope、依赖解析引擎、依赖树、冲突调解器 传递依赖、版本冲突、仓库优先级、依赖范围
自动构建 Ant、Gradle、Jenkins、JaCoCo、Make 生命周期、阶段、插件、目标、构建上下文 阶段顺序、插件绑定、继承关系、时序依赖
约定目录结构 Gradle 项目、IDE 项目结构、SonarQube 目录布局、资源处理器、编译路径、打包类型 目录层次、文件映射、IDE 识别规则、方位关系

五、"三化"定义

系统化:研究对象周围的事物,与研究对象平级。用于定位研究对象在更大系统中的位置,理解其同类、竞争者、协作方。

全局化:研究对象内部的事物,可解构后重构成研究对象。用于深入理解研究对象的内部组成、核心概念、工作机制。

结构化:系统化和全局化中搞到的事物之间的关系,包括因果关系、层次关系、方位关系、依赖关系、时序关系等。用于理解事物之间的联系和相互作用。


六、总结

不怕不知道,就怕不知道。知道自己不知道,不知道自己知不知道。

学习 Maven(或任何技术)的过程,就是从"不知道自己不知道"到"知道自己不知道",再到"知道自己知道"的过程。通过"三化"框架------系统化看周边、全局化看内部、结构化看关系------可以帮助我们更清晰地理解一个技术的全貌。

相关推荐
我是大猴子1 小时前
连接池+虚拟线程
java
小碗羊肉1 小时前
【RabbitMQ高级】如何保证消息的可靠性?
java·rabbitmq·java-rabbitmq
xiaoshuaishuai82 小时前
C# 多线程之间对比
java·开发语言·c#
越努力越幸运662 小时前
Java 无需 Office 环境实现 Word 转 HTML
java
用户8176967132352 小时前
Java OOM 排查完整指南:从告警到根因,MAT 堆分析全流程实战
java
要开心吖ZSH3 小时前
AI医疗分诊与健康咨询助手agent开发——(0)项目背景与概要
java·ai·agent·健康医疗·rag
后青春期的诗go3 小时前
泛微OA-E9与第三方系统集成开发企业级实战记录(十五)
java·泛微·集成开发·e9
吃口巧乐兹4 小时前
理解 Agent 中的 Slash Command:从概念到自定义命令实践
java·github
夕除5 小时前
shizhan--10
java·开发语言