1. Maven 简介
Maven 是一个项目管理和构建自动化工具,为 Java 项目提供了一个构建框架。它可以管理项目的构建、报告和文档。
1.1 Maven 的核心功能
- 依赖管理:自动下载和管理项目依赖的 jar 包
- 构建标准化:提供标准化的构建过程
- 项目信息管理:提供项目信息,如开发文档、开发者列表等
- 项目构建报告:生成项目文档和报告
1.2 Maven 的优势
- 简化构建过程
- 统一开发规范
- 提高开发效率
- 方便项目管理
- 可重用的构建逻辑
Maven 的核心理念是"约定优于配置",它提供了合理的默认行为,减少了大量的配置工作。
2. Maven 安装与配置
2.1 安装前提
Maven 是基于 Java 的工具,因此需要预先安装 JDK(Java Development Kit)。
- JDK 1.7 或更高版本
- 设置 JAVA_HOME 环境变量
2.2 下载与安装
- 从官方网站 https://maven.apache.org/download.cgi 下载最新版本的 Maven
- 解压下载的压缩文件到指定目录
- 设置环境变量:
- 设置 M2_HOME 环境变量为 Maven 安装目录
- 将 %M2_HOME%\bin 添加到 PATH 环境变量
2.3 验证安装
打开命令行终端,输入:
mvn -version
如果显示 Maven 版本信息,则安装成功。
2.4 配置文件
Maven 的主要配置文件是 settings.xml
,位于以下两个位置:
- 全局配置:Maven 安装目录下的
conf/settings.xml
- 用户配置:用户目录下的
.m2/settings.xml
用户级别的配置文件会覆盖全局配置。如果没有用户级别的配置文件,Maven 将使用全局配置。
2.5 离线环境配置
2.5.1 离线环境配置概述
在内网环境或无法访问外网的情况下,需要配置 Maven 离线环境,以便能够正常构建项目。这通常涉及配置本地仓库、修改 settings.xml 文件,并在 IDE 中设置离线模式。
2.5.2 配置本地仓库
首先,需要将外网环境中的本地仓库复制到内网环境中:
- 在外网环境中,找到 Maven 本地仓库(默认为
~/.m2/repository
) - 将整个仓库目录复制到内网环境的指定位置,例如
D:\App\DevApp\apache-maven-3.6.0\repository
2.5.3 修改 settings.xml 配置
在内网环境中,需要修改 Maven 的 settings.xml 文件(位于 D:\App\DevApp\apache-maven-3.6.0\conf\settings.xml
):
设置本地仓库路径
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:\App\DevApp\apache-maven-3.6.0\repository</localRepository>
...
</settings>
启用离线模式
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<offline>true</offline>
...
</settings>
配置镜像指向本地仓库
<mirrors>
<mirror>
<id>central</id>
<mirrorOf>*</mirrorOf>
<name>central</name>
<url>file://D:\App\DevApp\apache-maven-3.6.0\repository</url>
</mirror>
</mirrors>
2.5.4 删除 _remote.repositories 文件
为了确保 Maven 不会尝试从远程仓库下载依赖,需要删除仓库中的 _remote.repositories
文件:
Windows 环境下可以使用以下命令:
cd /d D:/App/DevApp/apache-maven-3.6.0/repository
for /r %i in (_remote.repositories) do del %i
Linux 环境下可以使用以下命令:
find /home/maven/localRepository -name "_remote.repositories" -exec grep -q "Could not transfer" {} \; -print -exec rm {} \;
2.5.5 IDE 配置
如果使用 IntelliJ IDEA,可以按照以下步骤配置离线模式:
- 打开 IDEA 设置(File > Settings)
- 导航到 Build, Execution, Deployment > Build Tools > Maven
- 勾选 "Offline work" 选项
- 点击 "Apply" 和 "OK" 保存设置
在命令行中执行 Maven 命令时,可以添加 -o
参数来启用离线模式,例如:mvn clean package -o
。不过,如果已经在 settings.xml 中设置了 <offline>true</offline>
,则不需要添加此参数。
在离线环境中,确保所有必要的依赖都已经包含在本地仓库中。如果缺少某些依赖,构建过程可能会失败。在这种情况下,需要在外网环境中预先下载所有必要的依赖,然后将它们添加到内网环境的本地仓库中。
3. POM 文件详解
3.1 什么是 POM
POM(Project Object Model)是 Maven 项目的核心配置文件,位于项目根目录下,文件名为 pom.xml
。它包含了项目的描述信息、依赖关系、构建设置等。
3.2 基础 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>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>My Application</name>
<description>Sample Maven Project</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3.3 POM 文件关键元素
元素 | 描述 |
---|---|
modelVersion | POM 模型版本(通常是 4.0.0) |
groupId | 项目组织唯一标识符,通常使用公司或组织域名的反向表示 |
artifactId | 项目唯一标识符,通常是项目名称 |
version | 项目版本号,SNAPSHOT 表示开发版本 |
packaging | 项目打包方式,如 jar、war、ear 等 |
dependencies | 项目依赖列表 |
properties | 自定义属性,可被其他元素引用 |
build | 构建配置,包括插件、资源等 |
4. 依赖管理
4.1 依赖声明
Maven 通过 POM 文件中的 <dependencies>
元素声明项目依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.9</version>
</dependency>
</dependencies>
4.2 依赖范围(Scope)
范围 | 描述 | 示例 |
---|---|---|
compile | 默认范围,编译、测试、运行时都有效 | Spring Core |
provided | 编译和测试有效,运行时由 JDK 或容器提供 | Servlet API |
runtime | 测试和运行时有效,编译时不需要 | JDBC 驱动 |
test | 仅在测试编译和测试运行时有效 | JUnit |
system | 类似 provided,但需要显式指定 jar 路径 | 本地系统依赖 |
import | 仅用于 dependencyManagement,导入依赖 | Spring BOM |
4.3 依赖传递
Maven 会自动引入项目依赖的依赖(称为传递性依赖)。例如,如果你的项目依赖 A,而 A 依赖 B,那么 B 也会自动成为你项目的依赖。
4.4 依赖排除
可以使用 <exclusions>
元素排除传递性依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.9</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
4.5 依赖冲突
当项目中存在同一依赖的不同版本时,Maven 会解决依赖冲突:
- 最短路径优先:路径短的依赖版本会被优先选择
- 声明顺序优先:如果路径长度相同,POM 文件中先声明的依赖版本会被选择
5. 构建生命周期
5.1 Maven 生命周期概述
Maven 构建生命周期是一系列阶段(phases)的序列,用于定义构建和分发项目的过程。Maven 定义了三个标准生命周期:
- clean:清理项目
- default:构建项目
- site:生成项目站点文档
5.2 Default 生命周期的主要阶段
阶段 | 描述 |
---|---|
validate | 验证项目是否正确且所有必要信息是否可用 |
compile | 编译项目的源代码 |
test | 使用合适的单元测试框架测试编译后的源代码 |
package | 将编译后的代码打包为可分发的格式,如 JAR |
verify | 对集成测试的结果进行检查,确保质量达标 |
install | 将包安装到本地仓库,供其他项目使用 |
deploy | 将最终的包复制到远程仓库,与其他开发者和项目共享 |
5.3 执行生命周期
可以通过命令行执行 Maven 生命周期的特定阶段:
mvn clean install
这个命令会先执行 clean 生命周期,然后执行 default 生命周期直到 install 阶段。
执行某个阶段时,Maven 会自动执行该阶段之前的所有阶段。例如,执行 mvn package
时,会自动执行 validate、compile、test 等阶段。
6. 插件使用
6.1 插件概述
Maven 的核心功能相对简单,主要依靠插件来执行具体的构建任务。插件是 Maven 的核心,每个构建阶段都绑定了一个或多个插件目标(goals)。
6.2 常用插件
插件名称 | 用途 |
---|---|
maven-compiler-plugin | 编译 Java 源代码 |
maven-surefire-plugin | 运行单元测试 |
maven-jar-plugin | 打包 JAR 文件 |
maven-war-plugin | 打包 WAR 文件 |
maven-source-plugin | 打包源代码 |
maven-javadoc-plugin | 生成 Javadoc |
maven-deploy-plugin | 部署到远程仓库 |
spring-boot-maven-plugin | Spring Boot 应用打包和运行 |
6.3 插件配置
可以在 POM 文件的 <build>
元素中配置插件:
<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>
6.4 插件执行
可以通过命令行直接执行插件目标:
mvn clean package
也可以直接执行特定插件的目标:
mvn compiler:compile
7. 仓库管理
7.1 仓库类型
Maven 使用不同类型的仓库来管理依赖:
- 本地仓库:位于本地计算机上,存储下载的依赖和构建的项目包
- 中央仓库:Maven 社区提供的默认仓库,包含大量的开源依赖
- 远程仓库:第三方或组织自己维护的仓库,可以存储私有依赖
7.2 本地仓库配置
本地仓库默认位于 ~/.m2/repository
,可以在 settings.xml
中修改:
<settings>
<localRepository>D:/maven-repository</localRepository>
</settings>
7.3 远程仓库配置
可以在 POM 文件中配置远程仓库:
<repositories>
<repository>
<id>company-repository</id>
<url>http://repository.company.com/maven2</url>
</repository>
</repositories>
7.4 镜像仓库
镜像仓库是中央仓库的一种替代品,可以提供更快的访问速度:
<mirrors>
<mirror>
<id>aliyun-maven</id>
<mirrorOf>central</mirrorOf>
<name>Aliyun Maven Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
在国内使用 Maven 时,建议配置阿里云等国内镜像,可以显著提高依赖下载速度。
8. 构建配置文件
8.1 什么是配置文件
Maven 配置文件(Profile)允许为不同环境(如开发、测试、生产)定义不同的构建配置。配置文件可以修改 POM 的某些部分,从而实现构建的灵活性。
8.2 配置文件类型
- POM 文件中的配置文件:定义在项目的 POM 文件中
- 用户级别的配置文件:定义在 Maven 用户设置中 (
~/.m2/settings.xml
) - 全局配置文件:定义在 Maven 全局设置中 (
$M2_HOME/conf/settings.xml
)
8.3 配置文件示例
<profiles>
<profile>
<id>dev</id>
<properties>
<db.url>jdbc:mysql://localhost:3306/devdb</db.url>
<log.level>DEBUG</log.level>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<db.url>jdbc:mysql://db-server:3306/proddb</db.url>
<log.level>ERROR</log.level>
</properties>
</profile>
</profiles>
8.4 激活配置文件
可以通过多种方式激活配置文件:
- 命令行:
mvn clean install -Pprod
- settings.xml:
<activeProfiles> <activeProfile>prod</activeProfile> </activeProfiles>
- 环境变量:可以根据环境变量的值激活配置文件
- 操作系统:可以根据操作系统类型激活配置文件
- 文件存在或不存在:可以根据文件的存在与否激活配置文件
9. 项目模板
9.1 什么是 Archetype
Maven Archetype 是一个项目模板工具包,用于快速创建符合特定模式的项目结构。它可以帮助开发者快速搭建项目骨架。
9.2 常用 Archetype
Archetype | 描述 |
---|---|
maven-archetype-quickstart | 创建简单的 Java 项目 |
maven-archetype-webapp | 创建简单的 Java Web 应用 |
spring-boot-starter-parent | 创建 Spring Boot 应用 |
9.3 使用 Archetype 创建项目
可以使用以下命令创建基于特定 Archetype 的项目:
mvn archetype:generate -DgroupId=com.example -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
9.4 自定义 Archetype
也可以创建自定义的 Archetype,用于满足特定的项目需求:
- 创建一个项目作为模板
- 使用
mvn archetype:create-from-project
命令从现有项目创建 Archetype - 安装或部署生成的 Archetype
- 使用自定义 Archetype 创建新项目
10. 多模块项目
10.1 多模块项目概述
多模块项目允许将一个大型项目拆分为若干个子模块,每个子模块可以独立构建,但又共享同一个父 POM。这种方式有助于更好地组织和管理复杂项目。
10.2 多模块项目结构
multi-module-project/
├── pom.xml # 父 POM
├── common/
│ └── pom.xml # 通用模块 POM
├── service/
│ └── pom.xml # 服务模块 POM
└── web/
└── pom.xml # Web 模块 POM
10.3 父 POM 配置
父 POM 需要指定打包方式为 pom,并列出所有子模块:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>multi-module-project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>service</module>
<module>web</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 在这里管理所有子模块共用的依赖 -->
</dependencies>
</dependencyManagement>
</project>
10.4 子模块 POM 配置
子模块 POM 需要指定父模块:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>multi-module-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<dependencies>
<!-- 该模块特有的依赖 -->
</dependencies>
</project>
10.5 模块间依赖
子模块之间可以相互依赖:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
构建多模块项目时,Maven 会自动解析模块间的依赖关系,确保按正确的顺序构建各个模块。
11. 最佳实践
11.1 依赖管理
- 使用
<dependencyManagement>
统一管理依赖版本 - 使用属性定义版本号,便于统一升级
- 定期检查依赖更新,尤其是安全更新
- 避免使用 SNAPSHOT 版本依赖于生产环境
- 使用依赖范围(scope)控制依赖传递
11.2 构建配置
- 遵循标准的目录结构
- 利用配置文件(profiles)进行环境隔离
- 使用插件管理统一插件版本
- 根据实际需求选择合适的打包类型
- 配置资源过滤,实现配置文件的动态替换
11.3 多模块项目
- 合理划分模块,保持模块的独立性
- 共享代码放在公共模块中
- 避免循环依赖
- 使用聚合构建简化命令
- 使用继承统一配置
11.4 持续集成
- 使用 Maven 与 CI 工具(如 Jenkins)集成
- 配置自动化测试
- 使用 site 插件生成项目文档
- 使用 checkstyle、PMD 等插件保证代码质量
- 配置自动部署流程
11.5 性能优化
- 使用并行构建:
mvn -T 4 clean install
- 配置合适的内存设置:
MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m"
- 使用增量构建
- 使用本地镜像仓库加速依赖下载
- 适当使用离线模式:
mvn -o clean install
随着项目的增长,定期审查 Maven 配置非常重要,确保其遵循最佳实践并满足项目需求。