Maven 是一个开源的项目管理工具,主要用于Java 项目的构建、依赖管理和项目生命周期管理。它由 Apache 软件基金会维护,是现代 Java 开发的重要工具之一。
Maven 的主要功能
1. 依赖管理
依赖管理是 Maven 的核心功能之一,简化了 Java 项目对第三方库的引用和版本管理。Maven 提供以下功能:
自动化下载: 在
pom.xml
文件中声明依赖后,Maven 会自动从中央仓库或配置的私有仓库下载依赖,并存储在本地仓库中 (~/.m2/repository
)。示例:
<dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> </dependencies>
传递依赖: 如果依赖的库本身依赖其他库(如 Spring 依赖 commons-logging),Maven 会自动解析这些传递依赖,避免手动添加每个依赖。
依赖冲突管理: Maven 使用最近声明的优先或最短路径优先规则,解决多个依赖版本冲突问题。
依赖范围: Maven 支持设置依赖的作用范围(scope),如:
compile
:默认范围,编译和运行时需要。provided
:编译时需要,但运行时由运行环境提供(如 Servlet API)。test
:仅在测试时需要。runtime
:运行时需要,但编译时不需要。
2. 项目构建
Maven 提供了一套标准化的构建流程,通过简单的命令即可完成从代码到最终可交付产品(如 JAR、WAR 包)的构建工作。
构建过程: Maven 的构建过程分为多个阶段,包括:
- 清理(
clean
):清除先前生成的输出(如目标目录target
)。 - 编译(
compile
):将源码编译为字节码。 - 测试(
test
):运行单元测试。 - 打包(
package
):生成可运行的 JAR/WAR 文件。 - 安装(
install
):将打包好的文件安装到本地仓库。 - 部署(
deploy
):将构建产物上传到远程仓库。
示例命令:
mvn clean package
- 清理(
跨平台一致性: Maven 提供统一的构建工具,确保在不同环境下(如开发环境、测试环境、生产环境)生成的产物一致。
3. 标准化的项目结构
Maven 强调“约定优于配置”,采用统一的项目目录结构,简化了开发者的项目配置工作。Maven 默认的目录结构如下:
- 主代码目录:
src/main/java
用于存放项目的主代码。 - 资源文件目录:
src/main/resources
用于存放配置文件或其他资源(如application.properties
)。 - 测试目录:
src/test/java
和src/test/resources
用于单元测试代码和测试资源。
这种结构减少了个性化配置,开发者和工具可以快速理解项目内容。
4. 多模块项目支持
Maven 支持多模块项目的管理,可以在一个主项目下管理多个子模块(子项目)。这种方式适用于大型系统开发。
父子关系: 父项目定义公共配置,子模块继承这些配置,从而避免重复声明。
父项目 POM 文件示例:
<modules> <module>module1</module> <module>module2</module> </modules>
独立构建和整体构建:
- 可以单独构建某个模块(
mvn clean install -pl module1
)。 - 也可以在父项目中一次性构建所有模块。
- 可以单独构建某个模块(
5. 插件机制
Maven 的核心功能通过插件实现,用户可以根据需求加载不同插件来扩展功能。
编译插件:
maven-compiler-plugin
用于控制代码编译,如指定 JDK 版本:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin>
测试插件:
maven-surefire-plugin
用于运行单元测试。打包插件:
maven-assembly-plugin
和maven-shade-plugin
用于生成 JAR 包或包含所有依赖的可执行 JAR。部署插件:
maven-deploy-plugin
用于将构建产物上传到远程仓库。
6. 生命周期管理
Maven 定义了项目生命周期的概念,将项目的构建过程划分为多个阶段,每个阶段对应具体的目标任务。Maven 的生命周期分为以下三种:
- 默认生命周期(Default Lifecycle): 用于构建项目,主要阶段包括:
validate
:验证项目是否正确。compile
:编译源代码。test
:运行单元测试。package
:将编译结果打包(如生成 JAR)。install
:将包安装到本地仓库。deploy
:将包发布到远程仓库。
- 清理生命周期(Clean Lifecycle): 用于清理构建环境,主要阶段包括:
pre-clean
:执行清理前的准备工作。clean
:删除先前生成的产物。post-clean
:执行清理后的任务。
- 站点生命周期(Site Lifecycle): 用于生成项目的文档网站,主要阶段包括:
pre-site
:执行文档生成前的准备工作。site
:生成文档。post-site
:执行文档生成后的任务。
- 执行阶段: 当运行某个阶段时,会自动执行之前的所有阶段。例如,运行
mvn package
,会执行validate
、compile
和test
阶段。
Maven 的核心概念
1. POM 文件
POM(Project Object Model)是 Maven 项目的核心配置文件,文件名固定为 pom.xml
。它描述了项目的基本信息、依赖关系、构建配置和插件配置等。
POM 文件的主要结构:
<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.example</groupId> <!-- 组名,标识组织或公司 -->
<artifactId>demo-app</artifactId> <!-- 项目名 -->
<version>1.0.0</version> <!-- 版本号 -->
<packaging>jar</packaging> <!-- 打包类型,默认为 jar -->
<!-- 项目依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
<!-- 构建插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
POM 文件的关键部分:
- 项目标识:
groupId
:通常对应组织名称(如域名反转形式:com.example
)。artifactId
:项目名称或模块名称。version
:项目版本号,例如1.0.0
或1.0.0-SNAPSHOT
。packaging
:指定打包类型,如jar
、war
、pom
。
- 依赖管理:
dependencies
用于声明项目的依赖项,Maven 会根据groupId
、artifactId
和version
下载对应的库。
- 插件配置:
build.plugins
用于配置构建所需的插件,如代码编译、测试执行、打包等。
- 继承和聚合:
- POM 支持父子项目关系(继承)和多模块管理(聚合)。
2. 仓库
Maven 仓库是存储依赖包和构建产物的地方,分为本地仓库、中央仓库和远程仓库。
类型和特点:
本地仓库:
- 位置:
~/.m2/repository
(默认路径)。 - 功能:缓存下载的依赖和项目构建生成的文件。
- 优点:避免重复下载,提升构建速度。
- 配置:可以通过
settings.xml
文件自定义本地仓库路径。
- 位置:
远程仓库:
- 中央仓库(Maven Central):Maven 的默认远程仓库,提供开源库的依赖下载。
- 私有仓库:公司或团队内部搭建的仓库(如 Nexus 或 Artifactory),用于存储内部开发的库或包。
- 配置:可以在
settings.xml
或pom.xml
中指定远程仓库。
示例:
<repositories> <repository> <id>my-company-repo</id> <url>http://repo.mycompany.com/maven2</url> </repository> </repositories>
快照(SNAPSHOT)与发布版本:
- 快照版本:用于开发阶段的版本,表示不稳定(如
1.0.0-SNAPSHOT
)。每次构建都会更新。 - 发布版本:用于正式发布,版本固定(如
1.0.0
)。构建结果不可更改。
- 快照版本:用于开发阶段的版本,表示不稳定(如
3. 依赖坐标
Maven 使用唯一的坐标来标识一个库。每个依赖都有以下几个主要属性:
groupId
:组名,通常表示组织或项目的归属。- 示例:
org.apache.commons
表示 Apache 的 Commons 项目。
- 示例:
artifactId
:库的名称,标识具体模块或项目。- 示例:
commons-lang3
表示 Apache 的 Commons Lang 库。
- 示例:
version
:版本号,标识具体的版本。- 示例:
3.12.0
表示 Commons Lang 的版本 3.12.0。
- 示例:
scope
:依赖的作用范围(可选)。compile
(默认):编译和运行时可用。provided
:编译时需要,但运行时由环境提供。test
:仅用于测试。runtime
:仅在运行时需要。system
:需要显式提供依赖的路径。
依赖声明示例:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
<scope>compile</scope>
</dependency>
传递依赖管理:
Maven 会自动解析传递依赖,但开发者可以通过以下方式控制:
排除传递依赖: 如果某些传递依赖不需要,可以显式排除:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.0.Final</version> <exclusions> <exclusion> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> </exclusion> </exclusions> </dependency>
依赖版本冲突解决: Maven 默认使用最近声明的依赖版本或路径最短的版本。开发者可以通过
<dependencyManagement>
显式指定版本:<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.1</version> </dependency> </dependencies> </dependencyManagement>
通过这些核心机制,Maven 实现了自动化依赖解析、统一构建流程和版本管理,大幅提升了开发效率和项目一致性。
Maven 的使用流程
1. 安装 Maven
下载和安装步骤:
下载 Maven:
- 访问 Maven 官方下载页面。
- 下载最新的二进制版本(Binary zip archive)。
解压:
- 将下载的文件解压到指定目录(如
C:\Program Files\Apache-Maven
)。
- 将下载的文件解压到指定目录(如
配置环境变量:
添加
MAVEN_HOME
:- 指向 Maven 解压路径,如
C:\Program Files\Apache-Maven
。
- 指向 Maven 解压路径,如
更新
PATH
环境变量:- 将
MAVEN_HOME\bin
添加到系统路径中。
- 将
验证安装:
打开命令行,输入:
mvn -v
如果显示 Maven 版本和 Java 版本,则安装成功。
2. 创建项目
使用 Maven Archetype 快速生成项目:
Maven 提供 archetype
插件,可以快速生成符合标准目录结构的项目。
运行命令:
mvn archetype:generate
选择项目模板:
- 运行命令后,Maven 会显示多个模板(archetype)。
- 选择一个合适的模板(如
maven-archetype-quickstart
)。
填写项目信息:
- 按提示输入以下信息:
groupId
:组织或公司名,如com.example
。artifactId
:项目名,如my-app
。version
:项目版本号,默认为1.0-SNAPSHOT
。
- 按提示输入以下信息:
项目生成:
- Maven 会根据输入的参数生成一个符合标准结构的项目目录。
目录结构示例:
my-app/
├── pom.xml (项目的核心配置文件)
├── src/
│ ├── main/
│ │ ├── java/ (主代码目录)
│ │ └── resources/ (资源文件目录)
│ └── test/
│ ├── java/ (测试代码目录)
│ └── resources/ (测试资源文件目录)
└── target/ (构建产物目录,运行 `mvn install` 后生成)
3. 管理依赖
依赖的声明:
Maven 使用 pom.xml
文件管理项目的依赖关系。所有需要的库可以通过在 <dependencies>
块中声明。
示例依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope> <!-- 仅测试阶段需要 -->
</dependency>
</dependencies>
如何找到依赖:
- Maven 中央仓库:
- 访问 Maven Central Repository。
- 搜索需要的库(如 Spring、JUnit),获取其
groupId
、artifactId
和version
。
- 本地仓库缓存:
- 下载的依赖存储在本地仓库路径中(默认:
~/.m2/repository
)。
- 下载的依赖存储在本地仓库路径中(默认:
4. 构建项目
Maven 提供的构建命令:
清理项目:
删除上次构建生成的临时文件:
mvn clean
清理后会删除
target
目录。
编译项目:
编译源代码:
mvn compile
编译后的
.class
文件会存储在target/classes
目录中。
运行单元测试:
执行项目的单元测试:
mvn test
测试结果会生成报告,存储在
target/surefire-reports
目录中。
打包项目:
根据项目类型(如 JAR、WAR),生成对应的打包文件:
mvn package
生成的包存储在
target
目录下(如my-app-1.0-SNAPSHOT.jar
)。
安装到本地仓库:
将构建好的包存储到本地仓库,以便其他项目引用:
mvn install
部署到远程仓库:
将构建的产物上传到配置的远程仓库:
mvn deploy
常用组合命令:
清理 + 编译 + 测试 + 打包 + 安装:
mvn clean install
5. 运行项目
在命令行运行 JAR 包:
运行生成的 JAR 包:
java -jar target/my-app-1.0-SNAPSHOT.jar
结合 Maven 插件直接运行:
- 如果项目使用
maven-assembly-plugin
或maven-shade-plugin
打包为可执行 JAR,可以直接运行。
- 如果项目使用
结合 IDE 管理和运行:
- 导入到 IntelliJ IDEA:
- 打开 IntelliJ IDEA,选择“Open”并加载项目的根目录。
- IDEA 会自动识别 Maven 项目并加载
pom.xml
。
- 运行项目:
- 配置运行目标(如主类
App.main()
)。 - 使用 IntelliJ 的运行功能直接启动项目。
- 配置运行目标(如主类
- 自动同步依赖:
- IDEA 会根据
pom.xml
自动下载依赖并添加到项目的 classpath 中。
- IDEA 会根据
Maven 的优点
- 自动化管理依赖,提升开发效率。
- 标准化的项目结构和构建流程,减少沟通成本。
- 插件丰富,适用场景广泛。
- 支持跨平台和跨团队协作。
常用 Maven 命令
1. mvn clean
作用:清理项目,删除上一次构建生成的文件和目录。
具体操作:
- 删除
target
目录中的所有文件,包括.class
文件、JAR/WAR 包、临时文件等。
- 删除
使用场景:
- 在重新构建项目之前清理旧的构建产物,确保构建环境干净。
示例:
mvn clean
2. mvn compile
作用:编译项目的主代码(
src/main/java
)。具体操作:
- 将
src/main/java
目录下的源代码编译为字节码文件,存放在target/classes
目录中。 - 不包括测试代码的编译。
- 将
使用场景:
- 检查代码的编译是否成功。
示例:
mvn compile
3. mvn test
作用:运行测试代码(
src/test/java
)。具体操作:
- 编译测试代码(
src/test/java
)。 - 使用指定的测试框架(如 JUnit 或 TestNG)运行单元测试。
- 生成测试报告,默认存储在
target/surefire-reports
目录中。
- 编译测试代码(
使用场景:
- 验证代码功能是否符合预期。
示例:
mvn test
4. mvn package
作用:打包项目为可执行文件(如 JAR、WAR)。
具体操作:
- 先运行
compile
和test
阶段。 - 根据项目类型(由
<packaging>
指定),将项目打包为 JAR 或 WAR 文件。 - 生成的文件存储在
target
目录中。
- 先运行
使用场景:
- 构建最终交付的文件(如库文件或可部署的应用程序)。
示例:
mvn package
5. mvn install
作用:将项目的构建产物安装到本地仓库。
具体操作:
- 运行
clean
、compile
、test
和package
阶段。 - 将生成的 JAR/WAR 包存储到本地仓库(默认路径:
~/.m2/repository
)。 - 本地仓库中的依赖可以被其他项目直接引用。
- 运行
使用场景:
- 本地项目之间的依赖共享。
示例:
mvn install
6. mvn deploy
作用:将项目的构建产物上传到远程仓库。
具体操作:
- 首先运行
install
阶段。 - 使用
distributionManagement
中配置的远程仓库地址,将 JAR/WAR 包上传。 - 通常需要配置用户凭据才能访问远程仓库。
- 首先运行
使用场景:
- 将项目发布到团队共享的远程仓库(如 Nexus 或 Artifactory)。
示例:
mvn deploy
补充:其他常用命令
1. 显示依赖树
命令:
mvn dependency:tree
作用:显示项目的依赖关系树,包括传递依赖。
使用场景:排查依赖冲突问题。
2. 强制更新快照版本
命令:
mvn clean install -U
作用:强制更新快照(
SNAPSHOT
)依赖,确保下载最新版本。
3. 跳过测试
命令:
mvn clean package -DskipTests
作用:跳过测试阶段,直接进行打包。
使用场景:快速构建测试无关的项目。
4. 运行目标类
命令:
mvn exec:java -Dexec.mainClass=com.example.App
作用:运行指定的主类(需引入
maven-exec-plugin
)。
文档信息
- 本文作者:RuanChuangStudio
- 本文链接:https://ruanchuangstudio.github.io//2024/12/16/maven-learn/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)