Maven 工具

为什么使用 Maven 构建工具

  1. 依赖管理
    1. 作为仓库功能,多个项目中可能会使用多个相同的 JAR 包,可以将可能使用到的 JAR 包放到 Maven 仓库中,通过 Maven 仓库引用减少各个项目之间对 JAR 包复制粘贴重复工作,减少下载时间和存储空间
    2. 通过 pom.xml 文件声明依赖,Maven 会自动从中央仓库(Maven Central Repository)或私有仓库下载所需库文件,避免手动管理 JAR 包的繁琐
    3. 自动解析依赖的依赖(传递性依赖),并通过版本仲裁机制解决版本冲突
  2. 标准化的项目结构
    1. 遵循  约定优于配置(Convention Over Configuration)  原则,强制规定项目目录结构(如  src/main/javasrc/test/resources),减少配置成本
    2. 开发者无需手动配置源码、测试代码、资源文件的位置,降低学习成本
  3. 统一的构建周期
  4. 定义了标准的构建生命周期(如  compiletestpackageinstalldeploy),通过简单的命令(如  mvn clean install)即可完成构建
  5. 丰富的插件生态
  6. 跨平台的可移植性
  7. 基于 Java 的 Maven 可以在任何支持 Java 的平台上运行(Windows、Linux、macOS),构建脚本(pom.xml)无需修改即可跨环境使用
  8. 与 CI 工具无缝集成
  9. 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  控制依赖的作用范围(如  compiletestprovided

控制依赖的作用范围(如  compiletestprovided),决定依赖在哪些阶段生效(编译、测试、运行等)

  • 构建配置
    • 定义构建生命周期 Build Lifecycle:通过绑定插件(Plugins)到 Maven 的生命周期阶段(如  compiletestpackage
  • 多模块项目管理
    • 聚合模块 Aggregation:通过  <modules>  标签管理多个子模块(Submodules)
    • 集成配置 Inheritance:通过  <parent>  标签继承父 POM 的配置,实现统一依赖版本管理

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>:控制依赖的作用范围(如  compiletestprovided),决定依赖在哪些阶段生效(编译、测试、运行等)

以上两个属性可能会影响依赖的传递

传递性依赖概念:当一个项目直接依赖某个库(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 中先声明的依赖的版本

参考

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值