maven
正在加载知识笔记
正在加载知识笔记
maven
时间****: 2025年04月28日 08:30
地点****: 硅谷北京校区
主讲人****: 赵伟风
课程版本****: maven 3.8.8
a. maven是为java项目工作的软件
b. maven软件本身实现就是用java语言(java_home****)
c. 具体功能:项目构建,依赖管理(jar)
a. 依赖(jar)管理 ****[掌握]
i. 我们需要编写少量xml配置文件
ii. 告知maven我们需要的依赖(jar)信息(gav)
iii. maven就会自动下载我们需要的依赖
iv. 自动下载依赖需要的依赖,确保依赖链的完整,以及版本无冲突
b. 项目构建
i. 项目源文件变成可执行文件的过程(构建)
ii. 现阶段Idea偷偷的帮我们进行构建,我们只需要点击运行按钮
iii. 将项目构建的过程交给maven管理
iv. 为什么项目构建要交给maven管理?
1. 不同的开发工具选择maven构建,可以保持相同的项目结构
2. maven的构建过程更加开放和透明,可以随意触发
a. http://maven.apache.org/download.cgi
b. 绿色解压版,只要解压即可
c. 解压的路径不能有中文和空格以及- 避免路径乱码问题
d. maven软件是用java语言编写,要求本机具备java_home环境变量
e. maven版本3.8.8 | jdk 7+ 即可

a. 需要系统变量中存在****JAVA_HOME
b. maven需要配置自己的home地址: MAVEN_HOME | M2_HOME : maven安装的根路径
c. maven需要配置path变量,方便使用mvn的命令: maven的\bin可执行文件 %MAVEN_HOME%\bin
d. 打开cmd mvn[空格]-v maven的版本,代表配置成功!
a. 本地仓库
默认缓存jar包位置: c:\users</font>用户.m2\repository文件夹中
:::tips
D:\maven\repository
:::
b. 国内镜像
:::tips
alimaven
aliyun maven
http://maven.aliyun.com/nexus/content/groups/public/
central
:::
c. jdk编译版本
java工程 - 构建和编译 - maven maven默认使用jdk1.5版本构建
:::tips
jdk-17
true
17
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
:::
a. 为什么maven项目会有gavp属性?
b. 答:maven项目不近在本地文件系统存储(文件夹名和项目),还有可能存储到maven仓库中!gavp就是maven在maven仓库中的标识
c. g -> groupId 公司或者组织的标识建议域名倒写,2-4层即可
d. a -> artifactId 项目文件的标识,建议和项目同名
e. v -> version 版本号,同一个项目不同时期的代码结构,建议三层命名法 x(主版本 模块改变).y(次版本 功能改变).z (修定号 bug)
f. p -> packaging 项目打包形式,项目的类型,不作为查找项目的标准! 因为加到maven仓库的项目只能是jar包 【jar(默认) war(web) pom】
a. 先准备一个empty工程 (java_maven_part)
b. 在empty工程上,右键创建maven工程
c. 选择构建工具,添加g a信息(v和p有默认值))
<?xml version="1.0" encoding="UTF-8"?>
<!--
声明这是一个 XML 文件,版本是 1.0,编码方式为 UTF-8。
所有的 pom.xml 文件都必须以这一行开头。
-->
<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">
<!--
<project>:POM(Project Object Model,项目对象模型)的根元素。
这三行属性是 XML 命名空间声明,用来告诉解析器该文件符合 Maven 的 POM 规范。
- xmlns:定义默认命名空间,表示当前文件遵循 Maven 的标准结构。
- xmlns:xsi:定义 XML Schema 实例的命名空间,用于校验 XML 格式。
- xsi:schemaLocation:指向 Maven 官方提供的 XSD 文件,用来验证文件格式是否合法。
-->
<modelVersion>4.0.0</modelVersion>
<!--
声明使用的 POM 模型版本。
“4.0.0” 是固定写法,表示使用 Maven 2.0+ 的标准 POM 模型版本。
-->
<groupId>org.example</groupId>
<!--
项目的“组织ID”或“公司域名反写”。
通常用于唯一标识一个组织或公司。
一般格式为:公司域名的反写 + 项目名,比如 com.company.project。
在这里是 org.example。
-->
<artifactId>_01maven_javase_project</artifactId>
<!--
项目的“构件ID”(artifact ID),即当前项目的名称。
它代表一个具体的模块或构件(例如一个 JAR 文件名)。
Maven 构建后的文件名通常是:artifactId-version.jar。
例如这里会生成文件:_01maven_javase_project-1.0-SNAPSHOT.jar。
-->
<version>1.0-SNAPSHOT</version>
<!--
当前项目的版本号。
通常有两种类型:
- 发布版本(release):如 1.0、2.3.1
- 快照版本(snapshot):如 1.0-SNAPSHOT(表示开发中的临时版本)
SNAPSHOT 版本在每次构建时都会被认为是“可变的”,适合开发阶段使用。
-->
</project>
<!--
结束 <project> 标签,表示整个 POM 文件定义完毕。
-->
d. 完成
a. 手动创建
i. 先创建javase的maven工程
ii. 补全web工程的文件结构
iii. 修改项目的打包方式(war)
iv. 刷新maven工程,出现小蓝点
b. 插件创建
i. 安装插件(JBLJavaToWeb)
ii. 先创建一个mavenjavase工程
iii. 项目 -》 右键 -》 JBLJavaToWeb插件(补全项目结构,修改打包方式)
iv. 刷新maven工程,出现小蓝点 (删除pom.xml多余空行,刷新即可!!)
i. 项目源文件经历一系列过程变成可执行文件
ii. 从idea的构建切换maven的构建(1.项目结构问题 2.maven的构建过程更加开放)
iii. 不管使用任何构建工具,构建的过程都是一致
iv. maven的构建场景下,我们需要掌握两个点: 1.什么时候需要我们主动构建 2.如何触发maven的构建
i. 清理:清理就是删除上一次构建的产物 【删除target文件夹】
ii. 编译:java编译成class文件存放在 target/classes文件夹中
iii. 测试:检查你的代码是否存在编译异常,可以批量执行单元测试代码
iv. 报告:会生成一个页面,这个页面包含我们项目的maven依赖信息 【鸡肋】
v. 打包:将maven工程进行打包,se工程就是jar | ee工程war包
vi. 部署:将maven项目的jar包加入到maven仓库中!!!供其他的maven项目使用!!
1. 本地部署(install): 将maven项目jar包添加到当前电脑的本地仓库,只能被当前电脑其他的项目使用
2. 私服部署 (deploy) :将maven项目jar包添加到公司的局域网仓库中,公司内的所有员工都可以使用
i. 清理项目:本次项目部署的内容和项目源文件不同 index.html -> 部署找不到index.html ****!!!
ii. 重新编译****:主动删除编译文件以后,一般都会主动触发下编译!!!
iii. 重新打包:将我们web项目打成war****包,交给运维人员进行部署!!!
iv. 项目部署:将mavenjar****包添加到本地仓库或者私服仓库!!
进入到项目的根路径下和pom.xml平级的位置,进行命令触发!
mvn 清理 clean 编译 compile 测试 test 报告 site 打包 package 部署 install 本地 deploy 私服
mvn clean
mvn 命令1 命名2 命令3....
war包打包插件和jdk版本不匹配:pom.xml 添加以下代码即可
<build>
<!-- jdk17和打war包和site插件版本插件不匹配 -->
<plugins>
<plugin>
</plugins>
</build>
i. 构建周期是一个构建动作的有序集合
ii. 触发同一个周期后的命令会自动触发同一个周期前的所有命令
i. 简化构建动作和行为
i. 清理周期:clean
ii. 默认(构建)周期:compile test package install deploy
iii. 报告周期:site
i. 清理数据:****mvn clean
ii. 重新编译:****mvn clean compile
iii. 重新打包:****mvn clean package
iv. 重新部署:****mvn clean install / deploy
i. 插件:打工人,真正进行构建的工具,直接选用插件构建过程极其繁琐
ii. 命令:包工头,对插件的一种封装,封装也比较简单,例如:测试 -> 包含三个插件,但没有前后的构建动作衔接能力
iii. 周期:经理,对构建动作的有序封装,触发后续动作会自动触发前序所有动作,极大的简化了构建行为
a. 依赖管理就是jar包管理
b. 我们以后不需要手动导入jar包了
c. 我们只要写少量的xml****配置(pom.xml)
d. maven就会自动帮我们下载我们的依赖
e. 自动下载依赖的依赖
f. 确保依赖链的完整,依赖之间版本不冲突
<!--
maven工程都有可能存储到maven仓库中! gav就是仓库中标识! p就是maven工程项目类型!!
groupId 公司或者组织的标识 域名倒写 2-4 [不会改变]
artifactId 项目名称和项目标识 [不会改变]
version 版本信息 x.y.z [会 改变时机: 将项目加入到maven仓库的时候才需要改变!!]
packaging 项目类型
jar [默认值,被其他项目引用的工具项目 才可以加入到maven仓库]
war 你是一个web项目,需要部署到服务器软中方可运行,注意不能放入maven仓库!!
pom 不打包!! 【继承和聚合】
-->
<groupId>com.atguigu.java</groupId>
<artifactId>05_maven_javase_pom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
a. 依赖管理添加
1. 使用maven提供的搜索网站即可 https://mvnrepository.com [访问速度]
2. 使用maven-search插件 【1.安装 maven-search 2.使用 tools / maven-search / 信息 / copy 】
3. 记载脑子里
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
</dependencies>
b. 依赖作用域[了解]
<scope标签 设置依赖的作用域和作用范围,设置依赖范围可以更精准的使用依赖以及避免报错!!
test main 打包运行
compile 1 1 1 绝大部分
provided 1 1 0 servlet(tomcat) [写代码需要,部署不需要,服务器自带的依赖]
runtime 0 0 1 mysql驱动 [反射 运行启动的! 平时不需要]
test 1 0 0 junit (@Test) spring-test spring-boot-starter-test
c. 依赖版本提取(版本号提取)
<properties标签中 【比dependencies靠上】 声明自定义标签 <标签 [规则:框架名.version]>版本</标签>
<dependencies <dependency <version>${标签名}
<properties>
<!-- 声明变量
标签名随便叫!! [语法角度]
规范: 1. 瞎叫 不知道是哪个依赖 2. 这些标签的参数会和maven内部的参数混合到一起! 切记有概率被覆盖!
总结规范:
1.标签要见名知意
2.不要单层命名标签,容易重复和覆盖
推荐: <框架名.version
-->
<spring.version>6.0.6</spring.version>
<junit.version>4.13.2</junit.version>
<druid.version>1.2.8</druid.version>
</properties>
<version>${druid.version}</version>
a. 检查网络状态(第一次下载需要进行阿里镜像连接)
b. 检查gav信息,是否报错 (前期不建议手写,粘贴即可)
c. 检查本地是否缓存lastupdated文件 (先删除文件(本地仓库+gav信息文件夹)再进行下载即可)
d. 反复下载失败(1. 复制别人仓库的依赖信息 2.像Javaweb学习一样,lib文件夹下粘贴jar包)
a. 打包命名设置
<!-- 1. 固定打包命名
默认项目打包的命名规则: artifactId - version . packaging
指定打包名称:<build <finalName>打包名称
-->
<finalName>maven</finalName>
b. 外部插件引入
<!-- 2. 外部插件引入
maven里面有 依赖 | 插件
依赖和插件的相同点: 都是maven工程(jar) , 都有gav属性
依赖和插件的不同点: 依赖 -》 给我们项目使用 -》 类似之前的导包
插件 -》 给maven使用的 -》 maven拥有的功能的具体实现 [maven工程才有需要,对maven进行功能完善或者扩展的]
maven的构建: 清理 编译 测试 打包 部署 -> 调用对应的插件进行真正的实现!!!
3.8.8 -》 自带构建插件 -》 插件的版本较低或者较高 -》 跟jdk17不匹配 -》 自己配置其他版本的插件即可
对于我们来说: 1. 理解插件和依赖的不同!! 2. 只要知道在哪配置插件即可
-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.9.1</version> <!-- 此处替换为你所需的版本号 -->
</plugin>
</plugins>
c. 控制内容打包
<!-- 3. 资源打包控制
maven项目结构
maven工程文件夹
src: 项目源代码
main : 项目主要文件
java: java代码
resources : 配置文件
webapp : web相关的内容
test : 项目测试代码
target: 构建完毕输出的文件的位置!
pom.xml maven依赖信息和构建的配置
正常情况下:你只要遵循maven的文件夹存放规则,即可自动进行文件编译和打包!!
不正常情况:你不按照文件夹的规则存放对应的文件夹类型!!不会直接报错,偷偷不给你打包!!
自定义打包控制:
需求1: 你要把我java文件夹下的所有内容都打包,除了.java
注意: 一旦你指定java文件夹的规则,maven很大概率也不管resources文件夹,也需要自己定义!!
-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
a. 依赖传递: 当我们下载某个依赖的时候,自动下载依赖所需要的依赖!!!
b. 传递作用: 1. 简化了依赖的导入 2.确保依赖版本无冲突 【尽量使用依赖传递特性】
c. 依赖终止: 1. 没有依赖可以传递 2. 非compile级别的依赖传递 3. 发生依赖冲突
d. 查看传递:1. 利用官网查看(导入前) 2. idea maven位置查看 (导入后)
a. 依赖冲突:在依赖传递的过程中,出现了重复依赖,就算依赖冲突,发生依赖冲突了不会在继续依赖传递!!
b. 依赖作用:1. 避免循环依赖 2.避免重复依赖
a. 依赖冲突选择原则
i. 谁短谁优先(第一原则):依赖路径短的优先被选中!
ii. 谁上谁优先(第二原则):第一原则无法区分,谁在xml中编写的位置靠上谁优先!
b. 总结
i. 我们尽量使用依赖传递特性导入依赖,后续发现有传递,尽量删除自己手动添加的依赖
ii. 依赖冲突不是坏事,避免重复依赖,原则上讲不需要我们参与,maven就会自动选择
iii. 一旦发生依赖冲突,是后续的所有依赖都不会传递!!!!
c. 依赖冲突手动排除
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
</exclusions>
</dependency>
聚合和继承是 Maven 高级应用的基石,特别是在开发大型项目(如微服务架构)时必不可少。简单来说:继承是为了复用配置,聚合是为了统一构建。
我们可以把它们想象成:
核心目的: 消除重复配置。
当多个模块都需要相同的依赖(比如都需要 junit 或 lombok)或者相同的版本号时,如果每个 pom.xml 都写一遍,维护起来非常痛苦。通过继承,子模块可以自动获得父模块的配置。
父工程的 pom.xml 必须满足两点:
<font style="color:#DF2A3F;">packaging</font> 必须是 <font style="color:#DF2A3F;">pom</font>。<font style="color:#DF2A3F;">dependencyManagement</font> 来管理版本。<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程通过 <parent> 标签指向父工程。
<parent>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>my-child-module</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
dependencies 与 dependencyManagement 的区别这是继承中最容易混淆的点:
dependencies** (在父工程中):** 这里的依赖会被强制传给所有子工程。也就是“强买强卖”,子工程不想用也得用。dependencyManagement** (在父工程中):** 这里只定义版本号,不引入依赖。子工程如果需要用,必须在自己的 pom 中声明(不写版本号)。这叫“推荐配置”,子工程有选择权。核心目的: 快速构建多个项目。
如果你有 10 个模块,没有聚合的话,你需要进入 10 个文件夹分别执行 mvn install。有了聚合,你只需要在“聚合工程”里执行一次命令,Maven 就会自动帮你把所有模块都构建好。
聚合工程通常也是一个 packaging 为 pom 的工程,使用 <modules> 标签。
<groupId>com.example</groupId>
<artifactId>my-aggregator</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>order-service</module>
<module>user-service</module>
<module>common-utils</module>
</modules>
当你在这个聚合工程目录下运行 mvn clean install 时,Maven 会分析模块间的依赖关系(比如 order-service 依赖 common-utils),然后按正确的顺序构建它们。
在实际开发中,继承和聚合通常是结合在一起使用的。通常会有一个“根节点”工程,它既是父工程(管理版本),又是聚合工程(管理构建)。
| 特性 | 继承 (Inheritance) | 聚合 (Aggregation) |
|---|---|---|
| 侧重点 | 纵向关系 (复用) | 横向关系 (统一管理) |
| 目的 | 统一版本,减少重复配置 | 一键构建多个模块 |
| 关键字 | <parent> | <modules> |
| 指向关系 | 子工程指向父工程 | 聚合工程指向子工程 |
| 目录结构 | 父工程通常在上一层,但也可以是任意位置 | 聚合工程通常在顶层目录 |
假设我们要开发一个电商项目,结构如下:
mall-project (根目录,既是父工程,也是聚合工程)
├── pom.xml (定义了 modules 和 dependencyManagement)
├── mall-common (公共工具类)
│ └── pom.xml (parent 指向 mall-project)
├── mall-order (订单服务)
│ └── pom.xml (parent 指向 mall-project,依赖 mall-common)
└── mall-user (用户服务)
└── pom.xml (parent 指向 mall-project)
1. 根目录 mall-project/pom.xml:
<groupId>com.example</groupId>
<artifactId>mall-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>mall-common</module>
<module>mall-order</module>
<module>mall-user</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
</dependencies>
</dependencyManagement>
2. 子模块 mall-common/pom.xml:
<parent>
<groupId>com.example</groupId>
<artifactId>mall-project</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>mall-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<parent>** + dependencyManagement)**。<modules>)。我能为你做的下一步:
需要我为你演示如何在 IDEA 中从零创建一个包含父子模块的 Spring Boot 项目吗?
1. maven安装和环境配置成功 【不需要回头再练一遍!!】
2. 创建mavenjavase和javaee项目 【不需要练】
3. maven的依赖管理 (1.导入依赖(提取版本,scope [junit]) 2. build finalName plugins resources) [20-30分钟]
4. maven的项目构建(清理数据,重新编译,重新打包,重新部署) [10分钟]
5. 依赖传递和依赖冲突了解和理解即可不需要额外练习
6. maven项目继承和聚合 20-30分钟 (继承统一版本管理,继承可以在父工程导入依赖,聚合批量构建)
7. 将javaweb阶段的快递管理转成maven javaee工程,依赖导入的时候需要提取版本信息<properties
知识笔记会随着实践和认知变化持续更新,不代表最终结论。