晚上好,愿这深深的夜色给你带来安宁,让温馨的夜晚抚平你一天的疲惫,美好的梦想在这个寂静的夜晚悄悄成长。
目录
[1.1 概念](#1.1 概念)
[什么是 Maven?](#什么是 Maven?)
[Maven 的核心概念](#Maven 的核心概念)
[1.2 maven依赖坐标](#1.2 maven依赖坐标)
[1.3 maven仓库](#1.3 maven仓库)
[1.4 maven安装](#1.4 maven安装)
[1.5 maven常用命令](#1.5 maven常用命令)
[1.6 maven生命周期](#1.6 maven生命周期)
[1.7 IDEA中集成maven(重点)](#1.7 IDEA中集成maven(重点))
[1.8 maven项目创建与导入](#1.8 maven项目创建与导入)
[1.8.1 maven项目创建](#1.8.1 maven项目创建)
[1.8.2 maven工程的导入](#1.8.2 maven工程的导入)
[1.9 maven依赖配置](#1.9 maven依赖配置)
[1.10 maven依赖范围](#1.10 maven依赖范围)
[2.1 概念与使用](#2.1 概念与使用)
[2.2 继承的内容](#2.2 继承的内容)
[2.3 自定义属性](#2.3 自定义属性)
[4. Maven继承和聚合的区别](#4. Maven继承和聚合的区别)
前言
在软件开发的日常工作中,有效的项目管理是确保项目成功的关键。Maven 是一个强大且广泛使用的项目管理工具,不仅仅是 Java 项目,它已经成为许多其他语言项目的选择。本文将深入探讨 Maven 的核心概念、工作原理及其在现代软件开发中的重要性。
一、Maven的基础使用
1.1 概念
什么是 Maven?
Maven 是一个基于项目对象模型(Project Object Model, POM)的构建工具,它主要用于自动****管理和构建Java项目。通过 Maven,开发人员可以更轻松地管理项目的构建、报告和文档生成。来源于apache使用Java语言实现的。
Maven 的核心概念
-
项目对象模型(POM):
- POM 是 Maven 中的关键概念,它是一个 XML 文件,描述了项目的配置信息、依赖关系和构建设置。POM 定义了项目的标识、依赖、插件、构建目标等。
-
依赖管理 :
传统使用jar包存在的问题: 1.下载麻烦, 2.项目体积变大,3.jar包冲突
- Maven 通过中央仓库(Central Repository)和其他远程仓库来管理项目依赖。通过简单地在 POM 中声明依赖,Maven 可以自动下载所需的库文件,并确保它们的版本兼容性和一致性。
-
生命周期和插件:
- Maven 提供了一组生命周期阶段,如
clean
、compile
、test
、package
等,每个阶段都与一个或多个插件相关联。插件提供了实现特定任务的能力,如编译代码、运行单元测试、打包应用程序等。
- Maven 提供了一组生命周期阶段,如
-
统一的项目结构:
1.2 maven依赖坐标
maven的其中一个功能是依赖管理,maven官方维护了一个服务器,该服务器上存放了目前所有公共的开源的jar包,使用maven的依赖管理功能可以自动从该服务器上下载指定的jar包。
maven坐标的作用: 用于唯一的定位maven中的一个jar包
maven坐标的组成:
- groupId: 指定公司(公司的域名)
- artifactId:指定项目(项目名)
- version: 版本
1.3 maven仓库
作用: 存储jar包的
分类:
- 中央仓库: maven官方维护的服务器(美国)上的某个文件夹。
- 远程仓库: 公司内部局域网中的某个服务器上的某个文件夹。
- 本地仓库: 程序员自己电脑上的某个文件夹。
Maven的云盘装机资料:
链接: https://pan.baidu.com/s/1dpawKgfRT01Iv_Cn5bY4Ew?pwd=1234 提取码: 1234
1.4 maven安装
1.解压资料中提供的maven安装文件到当前目录
2.把解压出来的文件夹拷贝到一个没有中文目录的文件夹中
3.配置本地仓库和镜像
在安装目录下提供了一个repository目录,该目录中我已经提前准备好了一些必须要使用的jar包(这些jar包将来使用的时候就无需去中央仓库下载)
在【安装目录/conf/settings.xml】配置文件中,进行配置本地仓库
在【安装目录/conf/settings.xml】配置文件中,进行配置镜像
4.配置环境变量
4.1 在用户变量中新建 MAVEN_HOME,变量的值就是maven的安装目录【bin目录的上一级目录】
4.2 在用户变量中的Path变量中,添加 %MAVEN_HOME%\bin
4.3 检测环境变量是否配置正确
1.5 maven常用命令
- clean: 清理之前编译好的内容
- compile: 用于编译当前工程
- test: 用于执行当前工程的测试代码
- package: 用于把当前的项目打成war|jar
- install: 用于把当前工程的jar包安装到本地仓库
- site: 用于生成当前工程的站点报告(api文档,说明书...)
- deploy: 用于将当前工程发布到远程仓库
1.在maven中,任何操作的背后,都是插件
2.在资料中,已经提前提供好了一个maven工程
验证命令:
**注意:**编译产生的内容在 当前工程的target目录中
1.6 maven生命周期
分类:
清理生命周期:
clean
默认生命周期: 同一生命周期内,后面的命令执行,那么前面的命令会自动执行。
compile,test,package,install,deploy
站点生命周期:
site
1.7 IDEA中集成maven(重点)
1.关闭当前工程
2.找到全局配置
3.找到maven相关的配置
4.完成本机自己安装的maven的配置
1.8 maven项目创建与导入
1.8.1 maven项目创建
1.创建项目
2.选择项目的类
3.填写当前工程详细信息
4.对pom.xml中的内容进行解释
1.8.2 maven工程的导入
注意:
在IDEA中,提供了maven操作的一些快捷面板,更好的操作和观察当前工程的maven的使用情况
1.9 maven依赖配置
位置: 需要在当前工程的pom.xml文件中完成配置
使用:
XML
<project>
<!--可以配置多个依赖-->
<dependencies>
<!--一个dependency标签,代表一个jar包依赖-->
<dependency>
<groupId>公司或者组织名</groupId>
<artifactId>项目名</artifactId>
<version>版本号</version>
</dependency>
<!--一个dependency标签,代表一个jar包依赖-->
<dependency>
<groupId>公司或者组织名</groupId>
<artifactId>项目名</artifactId>
<version>版本号</version>
</dependency>
</dependencies>
</project>
如果不知道依赖的坐标,可以上 https://mvnrepository.com/ 查找
注意: 当修改了pom.xml配置文件后,一定要记得刷新maven,这样配置才会生效(maven可以自动的帮你下载和加载指定的依赖)
XML
<?xml version="1.0" encoding="UTF-8"?>
<!--这是 XML 文件的声明,指定了 XML 的版本和字符编码-->
<!--这是 Maven 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- xmlns:xsi 和 xsi:schemaLocation 这些属性定义了 XML 文件中的命名空间和对应的 XML 模式(XSD)-->
<!--maven的模型版本。不要管-->
<!--当前工程的坐标-->
<groupId>com.itheima</groupId>
<artifactId>maven_p1</artifactId>
<version>1.0-SNAPSHOT</version>
<!--当前maven项目里的一些变量和值-->
<properties>
<!--编译maven项目使用的jdk版本,跟你创建工程时选中的jdk版本是一种的-->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<!--配置依赖-->
<dependencies>
<!--配置slf4j的依赖: 如果本地库中已经存在,则会有提示,如果本地库中不存在,去mvnrepository.com这个网站搜索并刷新当前maven-->
<dependency>
<!--公司名-->
<groupId>org.slf4j</groupId>
<!--项目名-->
<artifactId>slf4j-api</artifactId>
<!--版本-->
<version>1.7.26</version>
</dependency>
<!--logback-core依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!--logback-classic依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</project>
验证jar包的可用性
maven的传递依赖
如果A.jar中依赖了B.jar, 当前工程中引入了A.jar,此时当前工程也会传递依赖于B.jar
1.10 maven依赖范围
概念: 依赖生效的阶段
阶段:
- 源码: 测试源码和主程序源码
- 编译: 测试编译和主程序编译
- 运行: 测试运行和主程序运行
注意: 如果引入的依赖并没有指定依赖范围,那么默认在三个阶段全部生效
指定依赖的生效范围:
-
compile:
- 默认的依赖范围,适用于编译、测试和运行时。
- 依赖项将被包含在最终的打包文件(例如 JAR)中。
-
provided:
- 适用于编译和测试阶段,但在运行时由目标环境(如 Java EE 容器)提供。
- 这类依赖项不会被打包到最终的构建产物中(不会被包含在最终的部署包中)。简单来说:就是为了项目不报错,编译时要检查代码的语法和类型,骗骗IDEA。
- 比如Servlet API 就是一个典型的 provided 依赖。这意味着在编译和测试时需要依赖,但不会包含在最终的打包文件中。
- 编译过程需要依赖于一些库和依赖项,以便编译器能够找到并正确地编译代码中引用的类和接口。例如,如果你的代码中使用了某些第三方库(比如Apache Commons库),那么编译器在编译时就需要能够找到并使用这些库。
-
runtime:
- 依赖项仅在运行时可用,不参与编译和测试。
- 典型应用是像 JDBC驱动程序这样的库,在运行时由类加载器加载。在编译项目代码时并不需要这些驱动程序,只有在项目运行时才需要它们来连接数据库。
-
test:
- 仅在测试编译和运行测试代码时可用。
- 这些依赖项不会被包含在主项目的运行时或打包文件中。
-
system:
- 类似于 provided,但需要显式地提供 JAR 文件的路径。
- 不推荐使用,因为它打破了 Maven 的依赖解析机制。
- 在 Maven 构建系统中,system 依赖范围是指在构建项目时需要显式提供 JAR 文件的路径。这个范围下的依赖通常是不推荐使用的,因为它绕过了 Maven 的标准依赖管理机制,可能会导致构建不一致或不稳定的问题。
- systemPath 元素指定了 JAR 文件的路径。<systemPath>${project.basedir}/lib/example-lib-1.0.jar</systemPath>
-
import:
- 仅适用于 <dependencyManagement>部分的依赖项。
- 表示当前 POM 文件中声明的依赖管理部分应该被导入到依赖项集中。
扩展:<optional> 设置为true,则该依赖在打包的时候不会被打进jar包,同时不会通过依赖传递传递到依赖该项目的工程。
二、Maven的进阶
1.maven的分模块开发
2.maven继承
2.1 概念与使用
maven继承:简化依赖配置,统一管理依赖,将公共的依赖提取和统一版本管理(版本锁定)。
公共提取的好处:将共性的属性和依赖抽取出来,提高代码的重用性。属性和依赖需要修改时,只需在一个地方(父类)进行修改,所有子类都会继承这一变更,减少了维护的工作量。
父工程的**<dependencyManagement>**统一管理依赖版本,进行版本锁定,防止版本冲突。
版本锁定的好处:进行统一的版本管理,防止版本不一致引发的不必要的错误。
版本锁定的注意事项:这样只会加载版本,不会把依赖加载进去,谁用谁重写(并不需要指定版本)。
maven不支持多继承,支持多层继承。
2.2 继承的内容
-
依赖管理:
- 子项目可以继承父项目中声明的依赖项。这意味着父项目中定义的依赖库和版本信息可以在子项目中自动生效,无需重复声明。
-
插件配置:
- 父项目中配置的 Maven 插件可以被子项目继承和使用。这使得可以在父项目中统一管理和配置插件,而子项目则可以共享这些配置。
-
属性定义:
- 父项目中定义的属性可以在子项目中被继承和使用。例如,定义项目版本号、编译器版本等属性可以在所有子项目中共享和使用。
-
构建配置:
- 父项目中的构建配置(如构建插件的配置、构建目录的定义等)可以被子项目继承。这样可以确保所有项目在构建时遵循相同的规范和配置。
-
资源管理:
- 父项目中的资源过滤、资源目录配置等可以被子项目继承,从而实现资源的统一管理和共享。
扩展介绍:
设置打包方式为pom的作用:
- jar :普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
- war:普通web程序打包,需要部署在外部的tomcat服务器中运行
- pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理
设置 Maven 项目的打包方式为 pom 主要代表这个项目本身不会生成可执行的 Jar 文件或者 War 文件,而是作为父项目。因为父类项目只用于来简化项目管理和构建过程,连src目录都没有,你就算打包也没有意义。
所以父工程的打包方式应该为pom,这样打包不会生成可执行的构建产物。
设置relativePath的作用:
relativePath元素用于指定当前项目与其父项目之间的相对路径。
如果父项目的 pom.xml 文件不在本地仓库中(例如,正在开发中),那么可以通过 relativePath 元素指定父项目的相对路径,使 Maven 能够直接在指定路径中找到父项目的 pom.xml 文件。如果不指定会现在仓库中找,找不到就会报错。
2.3 自定义属性
定义方式:在<properties>标签中,通过标签声明。
使用方式:${属性名}。
-
简化配置管理: Maven的项目配置文件(
pom.xml
)中可能会包含大量重复的信息,例如版本号、路径等。通过定义自定义属性,可以将这些重复的信息抽取出来,集中管理,从而简化配置,减少配置文件的冗余和错误。 -
提高可维护性: 当项目中需要更新或者修改某些共享的信息时,如果没有使用自定义属性,可能需要逐个修改每个使用到这些信息的地方,这样容易出错且费时费力。而使用自定义属性后,只需要修改定义属性的地方,所有引用该属性的地方都会自动更新,大大提高了项目的可维护性。
-
增强灵活性: 自定义属性使得项目配置更加灵活和可配置化。例如,在不同的环境(开发、测试、生产)中,可以通过修改属性值来适应不同的环境需求,而不需要修改大量的代码或配置文件。
-
提高可读性和可理解性: 使用自定义属性可以使项目配置文件更加清晰和易于理解。定义了适当命名的属性可以使配置文件中的意图更加明确,降低了理解和维护成本。
3.maven的聚合
在 Maven 中,聚合(Aggregation)指的是将多个相关的 Maven 项目组织在一起,形成一个更大的项目,称为聚合项目或者父项目。聚合项目本身不包含实际的代码,它主要用来管理和组织其他子模块。这种模型使得你可以统一构建、测试、部署和发布多个相关的项目,从而提高项目管理的效率和一致性。
当一个模块需要打包的时候,需要想把父工程和依赖的工程打包才可以完成打包,相当麻烦。
maven聚合就是为了解决这个问题:
**将多个模块组织成一个整体,同时进行Maven插件操作。**让你实现项目一键构建、打包、安装等操作,因此我们无需根据依赖关系手动构建,直接在聚合工程构建即可(自动根据依赖关系构建,和顺序无关)。
如何使用聚合概念:
-
创建聚合项目:
- 首先,你需要创建一个新的 Maven 项目作为聚合项目。在创建项目的时候,需要选择
pom
作为项目的 packaging 类型,这样可以确保这个项目本身不包含任何实际的代码,只是用来管理其他子模块。
- 首先,你需要创建一个新的 Maven 项目作为聚合项目。在创建项目的时候,需要选择
-
定义子模块:
-
在聚合项目的 POM 文件中,使用
<modules>
元素列出所有的子模块。例如:java<modules> <module>submodule1</module> <module>submodule2</module> <!-- 可以列出所有的子模块 --> </modules>
-
这样定义后,Maven 就知道这个聚合项目管理着哪些子模块。
-
-
依赖管理:
- 聚合项目的 POM 文件可以定义全局的依赖管理和插件配置。这些配置会被所有子模块继承和共享,从而确保各个子模块使用的依赖库和构建插件保持一致性。
-
统一构建管理:
- 在进行构建时,可以在聚合项目的根目录下执行 Maven 命令(如
mvn clean install
),Maven 将会递归地构建所有列出的子模块。这样可以确保所有子模块都被正确构建和部署,而不需要单独进入每个子模块目录执行构建命令。
- 在进行构建时,可以在聚合项目的根目录下执行 Maven 命令(如
4. Maven继承和聚合的区别
在 Maven 中,"继承"(inheritance)和"聚合"(aggregation)是两种不同的关系模型,用于管理多模块项目的依赖和结构。
继承(Inheritance)
继承指的是 Maven POM 文件之间的父子关系。在 Maven 中,可以通过定义一个父 POM(通常是一个空的 POM,或者只包含通用配置的 POM)来统一管理子项目的配置和依赖。父 POM 中定义的配置和依赖会自动应用到所有子模块中。这样做的好处是可以减少重复配置,统一管理项目中的共享配置和依赖,提高项目的维护性和一致性。
聚合(Aggregation)
聚合指的是将多个 Maven 项目组织在一起形成一个更大的项目,通常是一个父项目(POM packaging)。聚合项目本身不包含实际的代码,它只是用来管理和组织其他子模块。通过聚合,可以将多个相关的项目(子模块)归为一体,方便统一构建、部署和管理。聚合项目的 POM 文件中指定了它所管理的子模块,因此它可以感知到哪些模块属于它的一部分。
主要区别
-
管理范围:
- 继承是从父 POM 向子 POM 传递配置和依赖信息,父 POM 可以定义全局的配置和依赖,子 POM 继承这些信息。
- 聚合是从一个父项目管理多个子项目,父项目本身可能并不包含实际的代码,只是用来组织和管理子项目。
-
POM 文件打包方式:
- 无论是继承还是聚合,它们的 POM 文件的 packaging 都是
pom
,这表示它们本身不会生成可执行的 artifact,而是用来管理其他项目或模块。
- 无论是继承还是聚合,它们的 POM 文件的 packaging 都是
-
关系感知性:
- 继承是单向的,父 POM 知道它有哪些子模块,但子模块并不知道它们是从哪个父 POM 继承的配置和依赖。
- 聚合是双向的,父项目(聚合项目)知道它管理的子模块,而子模块也知道它们属于哪个父项目(聚合项目)。
综上所述,继承和聚合在 Maven 中是两种不同的管理和组织项目结构的方式,各自有其独特的作用和适用场景。