介绍
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具,是一个项目管理和构建自动化工具,使用它来管理项目中的jar包;
- 管理jar冲突问题
- 公共代码重复利用
- 高效的项目开发需要高效的项目管理工具
- maven能处理从创建、编译、测试、部署 各个环节的项目管理
安装
目录结构
将下载好的Maven放到指定的目录下(任意),目录结构如下:
- bin:包含maven的运行脚本
- boot:包含一个类加载器的框架
- conf:包含Setting.xml配置文件
- lib:含有Maven运行时所需要的Java类库,也就是依赖的类库
环境变量
Maven依赖Java的环境变量(先配置好Java的环境变量),然后配置maven环境变量:
MAVEN_HOME=(为maven的根目录)
在PATH环境变量里加入%MAVEN_HOME%\bin;即可
控制台执行测试:mvn -v
仓库
仓库种类
Maven仓库不仅存放着依赖,而且管理着每个依赖的唯一标识,Java项目凭借坐标获取依赖;
当需要依赖时,会从仓库中寻找,顺序为:
1、本地仓库
2、私服(没有配置忽略)
3、公共仓库(没有配置忽略)
4、中央仓库
jar包在Maven的存储原理
GAV(坐标):G:group 群组、A:artifacts 项目、V:version 版本
-
-
如何导入依赖
-
项目建好之后需要通过坐标导入jar,添加坐标就会生成相应的依赖,删除则失效。
- 通过网址:https://mvnrepository.com/ 寻找依赖,获得相应的坐标;
- 在项目的pom文件中导入依赖坐标(格式如下);
- 同步依赖;
-
- 依赖管理
依赖的传递性
Maven中依赖是有传递性的,不管Maven项目存在多少间接依赖,POM中都只需要定义其直接依赖,不必定义任何间接依赖,Maven会动读取当前项目各个直接依赖的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中,能够帮助用户简化POM的配置。
通过依赖传递关系,可以使依赖关系树迅速增长到一个很大的量级,但很有可能会出现依赖重复,依赖冲突等情况,Maven针对这些情况提供了如下功能进行处理:
-
- 依赖范围(Dependency scope)
- 依赖调解(Dependency mediation)
- 可选依赖(Optional dependencies)
- 排除依赖(Excluded dependencies)
- 依赖管理(Dependency management)
依赖范围(scope)
我们可以在POM的依赖声明使用scope元素来控制依赖与三种classpath(编译 classpath、测试 classpath、运行 classpath )之间的关系,这就是依赖范围。
scope依赖项有6个常用的可选范围:
1)compile:默认值,表示编译依赖范围;适用于所有阶段(编译、测试、运行),会随着项目一起发布。表明该jar包一直全程存在/需要;
2)provided:表示已提供依赖范围;编译、测试时需要,运行时不需要,不会被打包。如servlet.jar;
3)runtime:表示运行时提供依赖范围;只在运行时使用,如JDBC驱动,适用运行和测试阶段;
4)test:表示测试依赖范围;测试时有效,用于编译和运行测试代码。不会随项目发布;
5)system:类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它(不推荐);
6)optional:当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用;
依赖范围与三种classpath 的关系:
依赖调节
Maven中用户只需要关心项目的直接依赖,而不必关心这些直接依赖会引入哪些间接依赖。但当一个间接依赖存在多条引入路径时,为了避免出现依赖重复的问题就会通过依赖调节来确定间接依赖的引入路径。
路径优先
当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高;
D是A的间接依赖,但两条引入情况上有两个不同的版本,不可以同时引入,否则造成重复依赖的问题。根据Maven依赖调节的第一个原则:引入路径短者优先,情况一的路径长度为 3,情况二的路径长度为2,因此间接依赖D将从A->E->D路径引入到A中。
声明优先
当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的;
优先使用第一条原则解决,第一条原则无法解决,再使用第二条原则解决;
排除依赖(exclusions)
排除依赖是控制当前项目是否使用其直接依赖传递下来的间接依赖;
- exclusions元素下可以包含若干个exclusion子元素,用于排除若干个间接依赖;
- exclusion元素用来设置具体排除的间接依赖,该元素包含两个子元素:groupId 和 artifactId,用来确定需要排除的间接依赖的坐标信息;
- exclusion元素中只需要设置groupId和artifactId 就可以确定需要排除的依赖,无需指定版本 version。
可选依赖(optional)
可选依赖用来控制当前依赖是否向下传递成为间接依赖;
- optional 默认值为 false,表示可以向下传递称为间接依赖;
- 若 optional 元素取值为 true,则表示当前依赖不能向下传递成为间接依赖。
排除依赖 vs 可选依赖
排除依赖和可选依赖都能在项目中将间接依赖排除在外,但两者实现机制却完全不一样。
- 排除依赖是控制当前项目是否使用其直接依赖传递下来的间接依赖;
- 可选依赖是控制当前项目的依赖是否向下传递;
- 可选依赖的优先级高于排除依赖;
- 若对于同一个间接依赖同时使用排除依赖和可选依赖进行设置,那么可选依赖的取值必须为false,否则排除依赖无法生效。
-
- pom.xml
参考资料:全面详解Maven的配置文件pom.xml(含常用plugin)_maven配置文件-优快云博客
pom.xml是Maven项目的核心配置文件,它是项目对象模型 - Project Object Model(POM)的缩写。POM定义了项目的所有属性,包括项目的名称、版本、依赖关系、构建配置等。使用pom.xml,我们可以轻松地管理项目的构建和依赖关系,让我们能够更专注于业务逻辑的开发。
项目基本信息
基本标签
与项目的基本信息相关的标签有很多,以下算必填项:
- groupId:项目的组名,通常是反转的域名,比如com.example。
- artifactId:项目的唯一标识符,通常是项目的名称。
- version:项目的版本号。
- packaging:项目的打包方式,通常是jar、war或pom,如果没有指定packaging,默认值是jar。
除了上面的几个标签,还有一些项目相关,但非必填的内容:
- name:项目名,可选项,提供项目的简短名称
- description:项目描述,可选项,提供项目的详细描述。
- version:项目主页,可选项,提供项目的网址。
- licenses: 许可证声明,可选项,声明项目所使用的一种或多种许可证
- developers:开发者信息,可选项,列出项目的开发人员。
- url:项目主页,可选项,提供项目的网址
modules
modules 标签用于声明当前 Maven 项目包含的模块子项目,每个子项目都是一个独立的 Maven 项目,具有自己的 pom.xml 文件,可以进行独立构建和测试。在父项目的 pom.xml 文件中,使用 标签来列出所有子项目的名称,如下所示:
上述代码表示当前项目是一个 Maven 的多模块项目:它包含了三个子项目 child1、child2 和 child3,这三个子项目与 parent-project 有相同的 groupId 和 version,但是 artifactId 不同,它们的 pom.xml 都位于 parent-project 的根目录下。当使用 Maven 命令在 parent-project 下执行构建时,Maven 会对每个子模块执行构建,最终生成子项目的构件并复制到 parent-project 的 target 目录下。
parent
parent 标签用于声明当前 Maven 项目的父项目,它可以将若干个 Maven 项目组织成一个整体,指定版本号,插件版本号等,便于管理和维护,在一个 Maven 项目中,使用标签来引用父项目,如下所示:
上述代码表示当前项目 child-project 是 parent-project 的子项目,它的 groupId 和 version 都继承自parent-project。relativePath元素是一个可选项,它的值是父项目 pom.xml 文件到子项目 pom.xml 文件的相对路径,如果子项目 pom.xml 和父项目 pom.xml 在同一目录下,则可以省略此元素。
properties
properties 严格来说,并不一定是项目本身的信息,而是人为设置的属性或者说宏,这个标签用来定义和管理项目中所需要的属性,其作用有以下几个:
- 统一管理项目中的常用属性,比如版本号、路径、插件版本等,方便统一修改和管理。
- 可以在配置过程中使用 ${…}占位符引用这些属性,使得配置更加灵活和便捷。
- 避免硬编码,提高代码的可维护性和可读性。
项目依赖列表
dependency
与项目的依赖列表相关的标签最外层由 <dependencies>来囊括,内部包含了各种具体的依赖<dependency>,该标签用于指定一个依赖项,它包含以下几个子标签:
- <groupId>:指定依赖项的groupId,项目的组名
- <artifactId>:指定依赖项的artifactId,项目的唯一标识符
- <version>:指定依赖项的版本号。
- <scope>:指定依赖项在项目中的使用范围。
其中的 <scope>一般包含以下几种范围:常用的有compile、test、provided 和 runtime
- compile:依赖库默认的 scope,表示该依赖库在编译、测试、运行时均需要使用。
- provided:表示该依赖库只在编译和测试时需要使用,而在运行时已经被系统或者容器提供,所以不需要打包到最终的应用程序中。
- runtime:表示该依赖库只在运行时需要使用,而在编译和测试时则不需要。
- test:表示该依赖库只在测试时需要使用,而在编译和运行时则不需要。比如说我们引入了 junit 包,但显然这个包我们不需要在打包时包含,只是用于测试,那么我们就可以将 junit 的 scope 设置为 test。
dependencyManagement
<dependencyManagement>相当于提前声明一个依赖,这里只是声明依赖,并不实现引入,而且可以被重写。
在不同的pom文件中,存在父子相互依赖关系的,父项目的pom中<dependencyManagement>中对该jar做了依赖,而子项目中<dependencies>又依赖了该jar,如果子项目中没有指定<version>和<scope>,则继承父项目中该jar的<version>和<scope>,如果子项目中指定了<version>和<scope>,以子项目的为准。
例如:有一个springmvc.jar,只有AB两个web项目需要,C项目是java项目不需要,那么又要怎么去依赖。如果AB中分别定义对springmvc.jar的依赖,当springmvc.jar版本变化时修改起来又会很麻烦。解决办法是在parent项目的pom文件中使用<dependencyManagement>将springmvc.jar管理起来,如果有哪个子项目要用,那么子项目在自己的pom文件中使用。
repository
当然,我们还能在pom文件中支持指定Maven仓库,即使用 <repositories> 和 <repository>标签,<repository>用于指定一个Maven仓库,它包含以下几个子标签:
- <id>:指定Maven仓库的ID。
- <name>:指定Maven仓库的名称。
- <url>:指定Maven仓库的URL
项目构建配置
build
build用于定义项目的构建配置,包括源代码目录、资源目录、插件等,其中代码部分的设置如下:
需要注意的是,像资源目录这种路径是没有默认值的,但根据Maven的约定优于配置原则(Convention over Configuration),Maven会使用默认的目录结构去查找源代码和测试代码。默认的目录结构如下:
因此,在一个标准的Maven项目中,sourceDirectory默认值应该是src/main/java。如果有自定义的代码目录结构,需要显式地设置sourceDirectory元素的值。
plugins
plugins的作用是定义 Maven 插件, plugins 主要用于扩展 Maven 的功能,帮助开发人员更方便地构建、打包、发布项目。插件可以通过 Maven 的插件中心或者自己构建的私有仓库来使用,能在构建过程中执行特定的任务,比如编译、打包、测试等。
插件的配置可以分为两种方式:全局配置和项目配置。全局配置是在 Maven 安装目录下的 conf/settings.xml 文件中进行配置,可以被所有的项目使用。项目配置则是在项目的 pom.xml 文件中进行配置,只对当前项目生效。
插件的使用主要分为以下几个步骤:
- 在 pom.xml 中声明插件依赖
- 配置插件的参数
- 运行插件命令
maven-compiler-plugin
最常用的编译功能, 各子标签的作用如下:
<source>:指定Java源代码的版本,例如1.8表示Java 8。
<target>:指定编译后的字节码版本,例如1.8表示Java 8。
<encoding>:指定源代码的编码格式。
<showWarnings>:是否显示编译警告信息,true表示显示,false表示不显示。
<compilerArgs>:可选参数,可以添加多个编译器参数,例如-Xlint选项用来启用编译器警告检查。
maven-release-plugin
maven-release-plugin 可以帮助我们在代码库中创建一个稳定的发布版本,并将其发布到Maven仓库中,同时更新开发版本号,以便于下次开发版本的迭代,它可以做如下配置
maven-install-plugin
当执行mvn instal命令时,maven-install-plugin 用于将一个特定的文件安装到本地Maven仓库中,以便其他项目可以使用它,例如在pom.xml中的配置如下:
maven-clean-plugin
maven-clean-plugin 用于清理Maven项目中的目标文件和构建临时文件,以便重新构建项目。它通常被用于在构建之前清理项目,以确保在构建时使用最新的代码和资源ar文件,在pom.xml中的配置如下:
-
- Maven命令
Maven进行构建(build)的主要环节如下:
- 清理:
mvn clean
会删除 target 目录及内容。 - 编译:
mvn compile
会将 src/main/java下的文件编译为class文件输出到target目录下。 - 测试:
mvn test
会执行src/test/java下的单元测试类,针对项目中的关键点进行单元测试。 - 打包:
mvn package
会在本地构建项目并将生成的jar或war文件打包到项目的target目录中。这个命令不会将生成的包安装到本地Maven仓库或远程仓库中(Java工程对应 jar 包,Web工程对应war包)。 - 安装:
mvn install
会执行 package 阶段的所有任务(编译、测试、打包),然后将打包好的文件安装到本地 Maven 仓库中,以便其他本地项目可以依赖它。 - 部署:
mvn deploy
将打包的结果部署到远程仓库或将包部署到服务器上运行。
注意:maven 命令要在IDEA的Terminal窗口执行,执行maven命令需要当前目录有pom依赖,可以用cd命令切换目录。