为什么使用 Maven 构建工具
- 依赖管理
- 作为仓库功能,多个项目中可能会使用多个相同的 JAR 包,可以将可能使用到的 JAR 包放到 Maven 仓库中,通过 Maven 仓库引用减少各个项目之间对 JAR 包复制粘贴重复工作,减少下载时间和存储空间
- 通过 pom.xml 文件声明依赖,Maven 会自动从中央仓库(Maven Central Repository)或私有仓库下载所需库文件,避免手动管理 JAR 包的繁琐
- 自动解析依赖的依赖(传递性依赖),并通过版本仲裁机制解决版本冲突
- 标准化的项目结构
- 遵循 约定优于配置(Convention Over Configuration) 原则,强制规定项目目录结构(如
src/main/java、src/test/resources),减少配置成本 - 开发者无需手动配置源码、测试代码、资源文件的位置,降低学习成本
- 遵循 约定优于配置(Convention Over Configuration) 原则,强制规定项目目录结构(如
- 统一的构建周期
- 定义了标准的构建生命周期(如
compile、test、package、install、deploy),通过简单的命令(如mvn clean install)即可完成构建 - 丰富的插件生态
- 跨平台的可移植性
- 基于 Java 的 Maven 可以在任何支持 Java 的平台上运行(Windows、Linux、macOS),构建脚本(
pom.xml)无需修改即可跨环境使用 - 与 CI 工具无缝集成
- Maven 是 Jenkins、GitLab CI、Travis CI 等工具的默认支持构建工具,便于实现自动化测试、打包和部署
什么是 Maven
- 基本概念:一款服务于 Java 平台的自动化构建平台
- 核心概念:一款项目管理工具 Project Management Tool,专注于 Java 项目的 构建(Build)、依赖管理(Dependency Management) 和 项目信息管理。它通过 约定优于配置 的原则,将构建流程标准化,同时提供丰富的插件生态,帮助开发者高效管理项目全生命周期
构建
- 概念:把动态的 Web 工程经过编译得到的结果部署到服务器上的整个过程,省流,将源代码转换为可运行或可部署的软件产物的完整过程。
其中包括依赖步骤
- 编译 Compile:Java 源文件 -> 编译 -> Class 字节码文件
- 测试 Test:运行单元测试
- 打包 Package:将编译后的代码、资源文件等打包为可分发的格式
- 验证 Verify:检查代码质量
- 部署 Deploy:将生成的包发布到服务器或仓库
POM 项目对象模型
POM (Project Object Management) 是 Maven 核心配置文件,以 pom.xml 文件的形式存在于项目根目录中
- 项目元数据
- 唯一标识项目:通过
groupId(组织标识)、artifactId(项目标识)、version(版本号)定义项目的 Maven 坐标 - 项目信息管理:包括名称(
name)、描述(description)、开发者(developers)、许可证(license)等
- 唯一标识项目:通过
- 依赖管理
- 声明依赖管理 Declare Dependencies:通过
<dependencies>标签定义项目所需的第三方库 - 自动解析依赖传递 Translative Dependencies:Maven 会自动下载依赖的依赖
- 依赖范围 Dependency Scope:通过
scope控制依赖的作用范围(如compile、test、provided)
- 声明依赖管理 Declare Dependencies:通过
控制依赖的作用范围(如
compile、test、provided),决定依赖在哪些阶段生效(编译、测试、运行等)
- 构建配置
- 定义构建生命周期 Build Lifecycle:通过绑定插件(Plugins)到 Maven 的生命周期阶段(如
compile、test、package)
- 定义构建生命周期 Build Lifecycle:通过绑定插件(Plugins)到 Maven 的生命周期阶段(如
- 多模块项目管理
- 聚合模块 Aggregation:通过
<modules>标签管理多个子模块(Submodules) - 集成配置 Inheritance:通过
<parent>标签继承父 POM 的配置,实现统一依赖版本管理
- 聚合模块 Aggregation:通过
Example:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 项目元数据 (Project Metadata) -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<!-- 多模块项目管理 (Multi-Module Project Management) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>cms-common</module>
</modules>
<!-- 依赖管理 (Dependency Management) -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 构建配置 (Build Configuration) -->
<build>
<!-- 项目的名字 -->
<finalName>WebMavenDemo</finalName>
<!-- 描述项目中资源的位置 -->
<resources>
<!-- 自定义资源1 -->
<resource>
<!-- 资源目录 -->
<directory>src/main/java</directory>
<!-- 包括哪些文件参与打包 -->
<includes>
<include>**/*.xml</include>
</includes>
<!-- 排除哪些文件不参与打包 -->
<excludes>
<exclude>**/*.txt</exclude>
<exclude>**/*.doc</exclude>
</excludes>
</resource>
</resources>
<!-- 设置构建时候的插件 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- 源代码编译版本 -->
<source>1.8</source>
<!-- 目标平台编译版本 -->
<target>1.8</target>
</configuration>
</plugin>
<!-- war插件(将项目打成war包) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- war包名字 -->
<warName>WebMavenDemo1</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
依赖范围
通过 scope 控制依赖的作用范围
- compile:默认值,适用于所有阶段(开发、测试、部署、运行)
- provided:只在开发、测试阶段使用,目的是不让 Servlet 容器和你本地仓库 JAR 包冲突 ,如servlet.jar
- runtime:只在运行时使用,如 JDBC 驱动,适用运行和测试阶段
- test:只在测试时使用,用于编译和运行测试代码。不会随项目发布。
- system:类似 provided ,需要显式提供包含依赖 JAR ,Maven 不会在 Repository 中查找它
Maven 的传递性依赖
<optional>:控制依赖的传递性,决定依赖是否传递给下游模块。<scope>:控制依赖的作用范围(如compile、test、provided),决定依赖在哪些阶段生效(编译、测试、运行等)
以上两个属性可能会影响依赖的传递
传递性依赖概念:当一个项目直接依赖某个库(A)时,Maven 会自动解析并引入该库(A)自身所依赖的其他库(B、C 等)。这种依赖的自动传递机制简化了依赖管理,避免了开发者手动声明所有间接依赖的繁琐操作。
当项目中依赖多个其他项目,从最底层项目
mvn install安装依赖最后到最顶层mvn install
核心逻辑:
- 依赖链(Dependency Chain):假设你的项目依赖库 A,而库 A 又依赖库 B,库 B 依赖库 C。根据传递性规则,Maven 会自动将 B 和 C 引入到你的项目中
- 自动解析(Automatic Resolution):Maven 通过分析
pom.xml中声明的依赖关系,递归下载所有直接和间接依赖(Transitive Dependencies),并将它们存储在本地仓库(Local Repository)中
如果 Dependencies 不属于 Maven 仓库中,需要先
mvn install将 Dependencies 安装到本地仓库中,后续才能引用
- 版本仲裁(Version Arbitration):如果多个依赖链中出现了同一库的不同版本,Maven 会根据 依赖调解(Dependency Mediation) 规则
- 最短路径优先(Nearest Definition):选择依赖链路径最短的版本
- 先声明优先(First Declaration):若路径长度相同,优先选择
pom.xml中先声明的依赖的版本


2046

被折叠的 条评论
为什么被折叠?



