Maven 与 IntelliJ IDEA 协作指南

一篇从「Maven 是什么」到「它如何与 IntelliJ IDEA 协作」的完整教学文档。结合官方文档与社区实践整理,适合需要彻底搞懂构建体系的 Java 开发者。


目录

  1. [Maven 在 Java 体系中的角色](#Maven 在 Java 体系中的角色)
  2. [Maven 核心概念:POM、坐标、仓库](#Maven 核心概念:POM、坐标、仓库)
  3. [Maven 的构建生命周期](#Maven 的构建生命周期)
  4. [依赖管理:Maven 最不可替代的价值](#依赖管理:Maven 最不可替代的价值)
  5. 标准目录结构
  6. [IntelliJ IDEA 与 Maven 是如何协作的](#IntelliJ IDEA 与 Maven 是如何协作的)
  7. [关键开关:Delegate IDE build/run actions to Maven](#关键开关:Delegate IDE build/run actions to Maven)
  8. 两套构建系统并存带来的坑(及规避)
  9. 常用命令速查

一、Maven 在 Java 体系中的角色

Apache Maven 是 Java 生态里最主流的构建管理与依赖管理工具 ,由 Apache 软件基金会维护,是 Java 开发的基石性工具What is Apache Maven? Build and dependency management for Java

需要先建立一个关键认知:Maven 是一个独立于任何 IDE 的工具 。它脱离 IntelliJ、Eclipse、VSCode 都能单独运行------只要装了 Maven,命令行敲 mvn 就能用。IDE 只是「集成」并「调用」它。

Maven 主要承担两大职能:依赖管理构建自动化 ELI5 - Maven。它基于 「约定优于配置」(convention over configuration) 的理念运作,通过统一的标准减少手工配置,从编译、测试一直管到打包和部署What is maven in devops?

Maven 的核心价值可以概括为:

  • 统一的构建方式 ------任何一个 Maven 项目,构建命令都一样(mvn package),换个项目也不用重新学。
  • 清晰的项目定义 ------pom.xml 一眼就能看出项目依赖什么、怎么构建。
  • 依赖共享与传递------自动从中央仓库下载并管理第三方库及其传递依赖。
  • 标准化项目结构 ------src/main/javatarget/ 这套约定就是 Maven 定的。

二、Maven 核心概念:POM、坐标、仓库

2.1 POM(Project Object Model)

每个使用 Maven 的项目,根目录下都有一个 POM 文件 pom.xml ,它描述了项目的依赖并告诉 Maven 如何构建项目What is Apache Maven?。POM 是 Maven 的「项目说明书」,是整个项目配置的唯一真相来源(single source of truth)

一个最小的 POM 必须配置三个要素:groupIdartifactIdversionIntroduction to the POM - Apache Maven

xml 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>

    <!-- 项目坐标:唯一标识一个构件 -->
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- 依赖声明 -->
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.10.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

2.2 坐标(Coordinates)

Maven 用一组「坐标」唯一定位一个构件,构件(artifact)正是由 Group ID 和 Artifact ID 的组合来标识,并可被其它项目当作依赖引用Maven Project: A Guide for Beginners

坐标元素 含义 示例
groupId 组织/团队的唯一标识,通常是倒置域名 org.springframework
artifactId 项目/模块名 spring-core
version 版本号(含 -SNAPSHOT 表示开发中版本) 6.1.0
packaging 打包类型 jar / war / pom

2.3 仓库(Repository)

当你在项目里声明一个依赖时,Maven 会在中央仓库中找到它,下载到本地仓库,再供项目使用What is Apache Maven?

  • 中央仓库(Central Repository):Maven 官方的公共仓库,绝大多数开源库都在这里。
  • 本地仓库(Local Repository) :默认在 ~/.m2/repository,下载过的依赖缓存在此,避免重复下载。
  • 私有/远程仓库(Private Repository):企业内部的 Nexus / Artifactory 等,用于存放内部构件。

三、Maven 的构建生命周期

Maven 有三套内置生命周期:default(默认/构建)clean(清理)site(站点文档) 。其中 default 生命周期负责项目的构建与部署,clean 生命周期负责清理Maven Tutorials: Maven Lifecycle, Phases \& Goal

3.1 default 生命周期的 7 个核心阶段(Phase)

default 生命周期实际包含约 23 个阶段,但下面 7 个是最该掌握的Maven Build Phases and Commands - GeeksforGeeks

阶段 作用
validate 校验项目是否正确、必要信息是否齐全
compile 编译 src/main/java 下的源码
test src/test/java 下的单元测试运行测试
package 把编译结果打包成 jar / war
verify 对集成测试结果做校验,检查质量
install 把打好的包安装到本地仓库,供本机其它项目依赖
deploy 把包发布到远程仓库,供团队共享

3.2 关键规则:阶段是「累积执行」的

阶段是有顺序的,当你执行某个阶段时,Maven 会自动按顺序先执行它之前的所有阶段 What are Maven goals and phases

例如运行 mvn install,Maven 会自动先跑 validatecompiletestpackageverify,最后才 installMaven Build Phases and Commands

复制代码
mvn install
  └─ validate → compile → test → package → verify → install   (全部自动按序执行)

3.3 Phase 与 Goal 的区别

  • Phase(阶段):生命周期里的一个有序步骤,本身是个「容器」。
  • Goal(目标) :插件提供的具体「动作」。在 Maven 里,「动词」是打包在插件中的 goal,它们被绑定到生命周期的某个 phase 上Chapter 4: The Build Lifecycle

一句话:你告诉 Maven 跑某个 phase,Maven 就会执行绑定在该 phase 上的所有 goal

3.4 clean 生命周期

clean 用于删除上一次构建产生的 target 目录,它包含 pre-cleancleanpost-clean 三个阶段;clean:clean 这个 goal 通过删除构建目录来清除构建输出Chapter 4: The Build Lifecycle

实践中常把 clean 和构建命令连用,以保证用全新的 target 目录构建:

bash 复制代码
mvn clean package   # 先删 target,再重新打包

⚠️ 重要提醒deploy 在 Maven 语境里指「把构件发布到远程 Maven 仓库供他人依赖」,不是指「把应用部署到服务器运行」。后者属于运维/CI-CD/容器层面的事,不在 Maven 标准生命周期的本意之内。


四、依赖管理:Maven 最不可替代的价值

Maven 是 Java 项目依赖管理事实上的标准工具Java Dependency Management with Maven。它解决了「手工下载 jar 包 + 手工解决版本冲突」这个痛点。

4.1 依赖作用域(scope)

通过 <scope> 控制依赖在哪个阶段可用:

scope 含义
compile(默认) 编译、测试、运行全程可用
provided 编译/测试可用,运行时由容器提供(如 Servlet API)
runtime 运行和测试时需要,编译时不需要(如 JDBC 驱动)
test 仅测试时可用(如 JUnit)

4.2 传递依赖与 dependencyManagement

Maven 会自动处理传递依赖(你依赖 A,A 依赖 B,Maven 自动帮你引入 B)。

在多模块项目中,<dependencyManagement> 用于集中管理依赖版本 :它本身不会真正引入依赖,而是提供一个版本参考,简化子模块后续添加依赖的工作Understanding pom.xml in Maven。子模块从父 POM 继承配置,保证多模块项目的一致性What is maven in devops?


五、标准目录结构

Maven 的「约定优于配置」最直观地体现在目录结构上:

复制代码
my-app/
├── pom.xml                      ← 项目说明书
├── src/
│   ├── main/
│   │   ├── java/                ← 主源码(compile 阶段编译)
│   │   └── resources/           ← 主资源文件(配置、静态文件)
│   └── test/
│       ├── java/                ← 测试源码
│       └── resources/           ← 测试资源
└── target/                      ← 构建产物(自动生成,可删)
    └── classes/                 ← 编译后的 .class 文件

target/ 是 Maven 的输出地盘,里面的内容都是自动生成的,可随时删除并重建。target/classes 就是 mvn compile.class 的默认位置。


六、IntelliJ IDEA 与 Maven 是如何协作的

这是本文档的核心。要点是:IntelliJ IDEA 自己有一套编译器和构建系统,Maven 是另一套------它们是两个独立的执行者。

对比项 IntelliJ 内建构建 Maven
谁执行 IDE 自己的 javac 封装 独立的 mvn 进程
配置来源 .idea/ 里的项目设置 pom.xml
默认输出目录 out/ target/
触发方式 Build → Build Project / 绿色运行键 Maven 工具面板 / mvn 命令
速度 快,支持增量编译 较慢,但与命令行/CI 完全一致

6.1 导入:以 pom.xml 为准重建项目模型

当你把项目作为 Maven 项目导入 IntelliJ 后,IDEA 会读取 pom.xml ,据此自动把依赖、模块、内容根、JDK 版本、构建目标等同步进 IDE。pom.xml 是 IDEA 项目模型的权威来源。

你可以在 IntelliJ 中链接、忽略项目,并在 Maven 与 IDEA 项目之间同步变更Maven projects \| IntelliJ IDEA Documentation。当 pom.xml 改动后,需要点 Maven 工具窗口里的 Sync/Reload All Maven Projects 图标重新同步Maven projects \| IntelliJ IDEA Documentation

6.2 Maven 工具窗口

IntelliJ 在右侧提供一个 Maven 工具面板 ,把生命周期阶段(clean / compile / test / package / install...)和插件 goal 以可视化方式列出来,点一下就相当于帮你拼好对应的 mvn 命令去执行。

6.3 日常 Build/Run 由谁干?取决于一个开关

默认情况下,你按 IDE 的 Build 按钮或绿色运行键时,用的是 IntelliJ 自己的编译器 (输出到 out/ 或你在 Project Structure 里配置的 Compiler output)。是否改为委托给 Maven,由下一节的开关决定。


七、关键开关:Delegate IDE build/run actions to Maven

7.1 在哪里

Settings/Preferences → Build, Execution, Deployment → Build Tools → Maven → Runner ,里面有个勾选框 Delegate IDE build/run actions to Maven :勾选它,就会通过 Maven 来 build、run 和 debug 代码Maven. Runner \| IntelliJ IDEA Documentation

如果你希望 IntelliJ 严格按照 Maven POM 来内部构建项目,就启用这个选项Ask IntelliJ to follow a Maven POM to build the project internally

7.2 勾选 vs 不勾选

不勾(默认) 勾上(委托 Maven)
编译者 IntelliJ 内建编译器 Maven(跑 pom.xml 配置的插件)
输出目录 out/ target/
速度 快,增量编译,适合日常开发 慢一些,但结果与命令行/CI 一致
插件执行 部分插件(代码生成、注解处理)不一定触发 pom.xml 里配的插件都会正常执行

7.3 什么时候该勾上

  1. 构建依赖 Maven 插件做"代码生成" ------比如 Protobuf/Thrift、注解处理器、企业内部脚手架插件等,会在 generate-sources 阶段生成 .java 源码。IDEA 自己的编译器不会执行这些插件,会出现「命令行能跑、IDE 跑不起来」「找不到生成的类」。勾上后就和命令行一致了。
  2. 要求与 CI/命令行构建结果严格一致------排查「本地 IDE 没问题、CI 却挂了」这类差异时,勾上能消除两套构建系统的不一致。
  3. 想让 IDEA 统一只用 target/ ------避免 out/target/ 两套产物并存导致的混乱。

这个开关在 WSL2 等环境下,也常被用来修复「Maven 项目找不到 imports / 无法运行」的问题Use Maven to Build and run your project in IntelliJ IDEA

7.4 代价

勾上后每次都走完整的 Maven 流程,编译/运行变慢、失去增量编译优势。因此多数人的折中做法是:平时不勾(享受快速增量编译),只在遇到「IDE 与命令行不一致 / 插件没生效」时临时勾上验证。


八、两套构建系统并存带来的坑(及规避)

这是同时用 IntelliJ + 另一个工具(如 VSCode 的 JDT、或自定义 Maven 插件)时最容易踩的雷。

8.1 「Build 很快成功,却找不到主类」

如果点 Build 后日志里只有 Copying resources...、没有 Compiling ... java files,说明 IDEA 认为「没有 Java 源码需要编译」,只搬了资源就结束。常见原因:

  • 源码目录没被标记为 Sources Root ------IDEA 只编译被标成 Sources(蓝色文件夹)的目录。结构被外部工具搞乱后,src/main/java 可能丢失该标记。
  • 增量编译缓存陈旧 ------之前用 mvn clean 或外部工具删了 target,但 IDEA 缓存仍认为「已是最新」,于是跳过编译,但目录其实是空的。

排查/修复

  1. 检查各模块 src/main/java 在项目树里是否为蓝色 ;不是就在 Project Structure → Modules → Sources 中重新标记,或在 Maven 面板 Reload All Maven Projects 让其按 pom.xml 重建。
  2. Build → Rebuild Project (而非 Build)强制全量重编,绕过缓存。正常会看到 Parsing java... / Writing classes... 字样。

8.2 IDEA 与 Maven 共用同一个 target/classes,互相覆盖

IDEA 的 Compiler output 默认就指向 target/classes,而 Maven 的 compile 产物也是 target/classes------两套系统写同一个目录,会互相覆盖/清除mvn clean 会删掉 IDEA 编的 class;IDEA Rebuild 也会清掉重写。这就导致 target/classes 时空时满、增量缓存与实际产物对不上,进而「找不到主类」。

两个稳定方案(二选一)

  • 方案一(推荐):统一走 Maven。勾上 Delegate IDE build/run actions to Maven,让编译、代码生成、输出全部由 Maven 一次性完整完成,不再有两套系统交替「半编译」的问题。
  • 方案二:保持各自编,但养成习惯 。跑过 mvn clean 或用过别的工具后,回 IDEA 先 Rebuild Project 再运行(别直接点运行,避免增量 Build 跳过编译);尽量不让两个 IDE 同时对同一项目做构建。

8.3 多 IDE 混用时的隔离建议

  • 给两个工具配置不同输出目录,互不干扰。
  • 把构建产物加入 .gitignoretarget/out/build/.classpath.project.settings/ 等。
  • 最省心:同一项目尽量只用一个 IDE 主力构建,另一个只读不构建。

九、常用命令速查

bash 复制代码
# 清理上次构建产物
mvn clean

# 编译主源码(产物到 target/classes)
mvn compile

# 运行单元测试
mvn test

# 打包成 jar/war(产物到 target/)
mvn package

# 先清理再打包(最常用的稳妥组合)
mvn clean package

# 安装到本地仓库 ~/.m2,供本机其它项目依赖
mvn install

# 发布到远程仓库,供团队共享
mvn deploy

# 跳过测试打包
mvn clean package -DskipTests

# 以 debug 模式输出详细日志
mvn clean install -X

总结

  • Maven 是独立于 IDE 的依赖管理 + 构建工具pom.xml 是它的配置核心,target/ 是它的产物目录。
  • IntelliJ IDEA 的角色是把 Maven 集成进来、可视化调用它 ,并以 pom.xml 为项目模型的权威来源;但 IDEA 自带的编译/构建与 Maven 是两套并存的系统
  • Delegate IDE build/run actions to Maven 这个开关决定 Build/Run 到底用 IDEA 编译器还是委托 Maven------对依赖代码生成插件的项目,勾上它能一劳永逸地避免「找不到类」。
  • 多套构建系统共用 target/classes 时容易互相覆盖,遇到「Build 成功却跑不起来」时,第一反应用 Rebuild Project,根治则统一走 Maven。

参考资料