1. Maven 简介
Maven
是一个强大的项目管理和构建工具,主要用于 Java
项目(但也支持其他语言,如 C#
、Ruby
等)。它提供了一种标准的方式来构建项目、管理依赖关系、生成文档等。
1.1 Maven 的核心概念
- POM (Project Object Model): 项目对象模型,使用
XML
文件描述项目 - 依赖管理: 自动下载和管理项目依赖
- 生命周期: 定义了一系列构建阶段
- 插件: 扩展
Maven
的功能 - 仓库: 存储依赖和插件的地方
2. Maven 安装与配置
我们可以通过 SDKMAN!
来安装 Maven
,也可以手动下载并安装。
推荐前者,可见安装与配置
| 版本 | 最低 JDK
要求 | 适用场景 | | Maven 3.6.x
| JDK 7+
| 旧项目兼容 | | Maven 3.8.x
| JDK 8+
| 主流稳定版(推荐 Java 8
使用)| | Maven 3.9.x
| JDK 8+
| 最新版(推荐 Java 11+
使用)|
3. Maven 项目结构
利用 Maven
初始化项目:
mvn archetype:generate
执行上述命令后,根据引导,输入信息后,会自动创建一个项目。
或者也可以手动指定模板:
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=my-webapp5 \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
标准的 Maven
项目结构如下:
project
├── src
│ ├── main
│ │ ├── java # 源代码
│ │ ├── resources # 资源文件
│ │ └── webapp # Web 应用文件
│ └── test
│ ├── java # 测试代码
│ └── resources # 测试资源
├── target # 构建输出目录
└── pom.xml # 项目配置文件
TIP
Maven
安装依赖,是从 Maven Central
(全称 Maven Central Repository
)下载的。
Maven Central
是 Java
生态中最主要的公共依赖库托管中心。
它的在线地址是https://search.maven.org, 类似于 npmjs.com
4. POM 文件详解
4.1 基本配置
<project>
<!-- 必须字段:POM 模型版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 项目坐标(唯一标识) -->
<groupId>com.example</groupId> <!-- 组织名(如公司域名) -->
<artifactId>my-app</artifactId> <!-- 项目名 -->
<version>1.0.0</version> <!-- 版本号 -->
<packaging>jar</packaging> <!-- 打包类型(jar/war/pom) -->
<!-- 项目元信息 -->
<name>My Application</name> <!-- 项目显示名称 -->
<description>A demo project</description>
<!-- 依赖管理 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope> <!-- 依赖作用域(test/compile/runtime等) -->
</dependency>
</dependencies>
<!-- 构建配置 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- 指定源码版本 -->
<target>1.8</target> <!-- 指定目标字节码版本 -->
</configuration>
</plugin>
</plugins>
</build>
<!-- 多模块项目管理 想象成monorepo -->
<modules>
<module>sub-module</module> <!-- 子模块目录名 -->
</modules>
<!-- 父项目继承 -->
<parent>
<groupId>com.parent</groupId>
<artifactId>parent-project</artifactId>
<version>1.0</version>
</parent>
</project>
TIP
dependencies
与 dependencyManagement
:
dependencies
是依赖的管理,用于管理依赖的版本、范围等。相当于npm package.json
中的dependencies
。dependencyManagement
是用于管理依赖的依赖版本(常和parent
配合)。有点类似于npm package.json
中的resolutions
。
4.2 依赖范围(Scope)
compile
: 默认范围,编译和运行时都可用provided
: 编译时可用,运行时由容器提供runtime
: 运行时可用,编译时不需要test
: 仅在测试时可用system
: 类似 provided,但需要显式指定路径
5. Maven 生命周期
Maven
的生命周期是由一系列预定义的阶段(phase
)组成的,每个阶段代表构建过程中的某个步骤。
Maven
的生命周期可以分为 清理生命周期、默认生命周期 和 站点生命周期。
5.1 清理生命周期(Clean Lifecycle)
清理生命周期负责清除项目的临时文件和输出文件。
| 阶段(Phase
) | 描述 | | pre-clean
| 在清理之前执行,可以用来执行任何需要的预处理。 | | clean
| 删除 target
目录,清理项目输出。 | | post-clean
| 清理之后执行,可以用来执行任何清理后的操作。 |
5.2 默认生命周期(Default Lifecycle)
默认生命周期涉及到项目的构建、测试和打包等过程。
| 阶段(Phase
) | 描述 | | validate
| 验证项目是否正确,所有的必要信息是否可用。| | compile
| 编译项目的源代码。 | | test
| 运行单元测试,通常依赖于 JUnit
等测试框架。 | | package
| 将项目打包成 JAR
、WAR
、EAR
等格式。 | | verify
| 运行任何必要的验证,以确保项目是有效的,通常是运行集成测试等。 | | install
| 将构建的 artifact
(如 JAR
、WAR
文件等)安装到本地仓库(~/.m2/repository
)。| | deploy
| 将 artifact
上传到远程仓库。|
TIP
mvn
的依赖安装都是在本地全局仓库下 ~/.m2/repository
,这一点与前端项目中的node_modules
不同。
这是因为:
- 依赖复用性:
Java
依赖通常较大(如Spring
、Hibernate
),全局存储避免重复下载。 - 版本一致性:通过
pom.xml
的<version>
精确控制依赖版本,减少冲突。 - 构建效率:已下载的依赖会被缓存,加速后续构建。
5.3 站点生命周期(Site Lifecycle)
站点生命周期负责项目的文档和报告生成。
| 阶段(Phase) | 描述 | | pre-site
| 在生成站点之前执行,可以用于执行某些前置操作。| | site
| 生成项目的站点文档(例如 HTML
格式的报告)。| | post-site
| 生成站点后执行,用于进行清理等后置操作。| | site-deploy
| 将生成的站点发布到远程服务器(例如将文档上传到网站)。|
6. JAR 和 WAR
JAR
(Java Archive)和 WAR
(Web Application Archive)是 Java
中两种常见的打包格式,它们的用途和结构有显著区别:
| 特性 | JAR
| WAR
| | 全称 | Java Archive
| Web Application Archive
| | 用途 | 普通 Java
库或可执行程序 | 部署到 Servlet
容器的 Web
应用 | | 打包类型 | <packaging>jar</packaging>
| <packaging>war</packaging>
| | 运行方式 | 命令行或嵌入其他应用 | 需部署到 Tomcat/Jetty
等容器 | | 包含内容 | 类文件、资源文件、依赖库(可选) | 类文件、JSP
、HTML
、WEB-INF
、依赖库 |
JAR 文件结构:
my-app.jar
│
├── META-INF/
│ └── MANIFEST.MF # 定义主类、依赖等
├── com/
│ └── example/
│ └── Main.class # 编译后的类文件
└── lib/ # 依赖库(如果打包为 fat-jar)
WAR 文件结构:
my-webapp.war
│
├── WEB-INF/
│ ├── web.xml # Web 应用描述文件(Servlet 3.0+ 可选)
│ ├── classes/ # 编译后的类文件(如 Servlets)
│ └── lib/ # 依赖库(如 JDBC 驱动)
├── index.jsp # 前端页面
├── static/
│ ├── css/style.css
│ └── js/app.js
└── META-INF/ # 容器相关配置
TIP
如果 java
项目要打成 jar
包的话,需要额外注意下 maven-jar-plugin
的配置:
<!-- pom.xml -->
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.App</mainClass> <!-- ⚠️ 换成你的主类路径 -->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
然后执行 mvn clean package
打包出 jar
包。
运行 jar
包:
java -jar target/my-app.jar
7. 使用注意事项
7.1 最佳实践
依赖管理
- 使用最新稳定版本
- 避免使用
system
范围 - 定期更新依赖版本
- 使用
dependencyManagement
统一管理版本
构建优化
- 使用
-T
参数进行并行构建 - 合理配置
settings.xml
- 使用本地仓库镜像加速构建
- 使用
插件使用
- 使用最新版本的插件
- 避免使用过时的插件
- 合理配置插件参数
7.2 常见问题解决
依赖冲突
- 使用
mvn dependency:tree
查看依赖树 - 使用
exclusions
排除冲突依赖 - 使用
dependencyManagement
统一版本
- 使用
构建失败
- 检查网络连接
- 清理本地仓库
- 检查 POM 文件配置
性能优化
- 使用本地仓库镜像
- 配置合适的 JVM 参数
- 使用并行构建
8. 高级特性
8.1 多模块项目
<modules>
<module>module1</module>
<module>module2</module>
</modules>
8.2 属性管理
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
8.3 构建配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>