Maven学习01 - 常用命令、坐标概念与依赖管理

本文详细介绍了Maven的常用命令,如编译、测试、打包和安装,以及坐标的概念,包括groupId、artifactId和version。此外,重点讨论了Maven的依赖管理,包括依赖的详细配置、范围(scope)、传递性、排除和冲突解决。通过实例展示了如何配置和管理依赖,以及理解不同依赖范围在项目中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Maven学习01 - 常用命令、坐标概念与依赖管理

1. Maven常用命令

mvn compile 编译,将Java 源程序编译成 class 字节码⽂件。
mvn test 测试,并⽣成测试报告
mvn clean 将以前编译得到的旧的 class 字节码⽂件删除
mvn pakage 将工程中所有目录、文件封装到一个压缩包中,Java工程:jar包;Web工程:war包。(打包成jar包或者war包由pom文件中标签决定)
mvn install 将项⽬⽣成 jar 包放在仓库中,以便别的模块调⽤

package 与 install的 区别

  • 1.install:打包好的 jar 包会安装到本地的 maven 仓库中,使用的配置是默认的配置,供其他项目使用
  • 2.package 指定参数打包:clean package -Dmaven.test.skip=true -Pprod 这种方式就是指定了打包的参数,并且打包后的文件存放到项目的 target 目录下。
  • mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。
  • mvn clean install依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段。
  • mvn clean deploy依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段。
  • package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
  • install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库
  • deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

2. Maven 坐标的概念和依赖管理

1) 什么是坐标

数学中的坐标

在平⾯上,使⽤ X 、Y 两个向量可以唯⼀的定位平⾯中的任何⼀个点

在空间中,使⽤ X、Y、Z 三个向量可以唯⼀的定位空间中的任意⼀个点

Maven中的坐标

俗称 gav:使⽤下⾯三个向量⼦仓库中唯⼀定位⼀个 Maven ⼯程

在项⽬中的 pom.xml ⽂件中,我们可以看到下⾯ gav 的定义

  • groupid:公司或组织域名倒序 : com.seafyliang.maven

  • artifactid:模块名,也是实际项⽬的名称: Maven_05

  • version:当前项⽬的版本:0.0.1-SNAPSHOT

在这里插入图片描述

Maven坐标和仓库,jar包的关系

什么是仓库,后⾯我们会详细讲解,现在你只需要知道是 Maven ⽤来存放 jar 包的地⽅。

那么依照上⾯定义的 gav,我们执⾏ mvn -install 命令,会出现什么情况呢?

⾸先进⼊到我们上⾯讲过的 settings.xml ⽂件配置的仓库⽬录。

将我们上⾯配置的 gav 向量组合起来就是⽬录:

com/ys/maven/Maven_05/0.0.1-SNAPSHOT/Maven_05-0.0.1-SNAPSHOT.jar

在这里插入图片描述

其次,我们观察打出来的 jar 包:Maven_05-0.0.1-SNAPSHOT.jar,也就是 artifactid-version.jar

2) Maven依赖

什么是 依赖 ?相信有过⼀定开发经验的⼈知道,每当我们需要使⽤某个框架时,⽐如 SpringMVC,那么我们需要导⼊相应的 jar 包,但是⼿动导⼊包的时候,往往会漏掉⼏个 jar 包,那么在使⽤该框架的时候系统就会报错。那么我们就说导⼊的包与未导⼊的包存在依赖关系。⽽使⽤ Maven,我们只需要在pom.xml ⽂件中进⾏相应的配置,它就会帮助我们⾃动管理 jar 包之间的依赖关系。那么它是怎么管理的呢,接下来我们会详细讲解。

3)依赖的详细配置

我们以 Junit 为例,在 pom.xml ⽂件中进⾏详细⽽完整的配置。

<project> 
	<dependencies>
  	<dependency> 			
  		<groupId>junit</groupId> 
      <artifactId>junit</artifactId>
      <version>3.8.1</version> 
      <type>...</type> 
      <scope>...</scope> 
      <optional>...</optional>
			<exclusions> 
				<exclusion> 
					<groupId>...</groupId> 
					<artifactId>...</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
</project>
  • dependencies:⼀个 pom.xml ⽂件中只能存在⼀个这样的标签。⽤来管理依赖的总标签。
  • dependency: 包含在 dependencies 标签中,可以有⽆数个,每⼀个表示⼀个依赖
  • groupId、artifactId 和 version:依赖的基本坐标,对于任何⼀个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。
  • type:依赖的类型,对应于项⽬坐标定义的 packaging。⼤部分情况下,该元素不必声明,其默认值是 jar。
  • scope:依赖的范围,默认值是 compile。后⾯会进⾏详解。
  • optional:标记依赖是否可选。
  • exclusions:⽤来排除传递性依赖,后⾯会进⾏详细介绍。

4)依赖的范围scope

在这里插入图片描述

⼀般情况下,我们对前⾯三个依赖⽤的⽐较多。下⾯的主程序表示 maven ⽬录结构 src/main/java.测试

程序⽬录结构为:src/test/java

  • compile 范围依赖

对主程序是否有效:有效

对测试程序是否有效:有效

是否参与打包:参与

是否参与部署:参与

典型例⼦:log4j

  • test 范围依赖

对主程序是否有效:⽆效

对测试程序是否有效:有效

是否参与打包:不参与

是否参与部署:不参与

典型例⼦:Junit

  • provided 范围依赖

对主程序是否有效:有效

对测试程序是否有效:有效

是否参与打包:不参与

是否参与部署:不参与

典型例⼦:servlet-api.jar,⼀般在发布到 服务器中,⽐如 tomcat,服务器会⾃带 servlet-api.jar 包,

所以provided 范围依赖只在编译测试有效。

  • runtime 范围依赖:

在测试、运⾏的时候依赖,在编译的时候不依赖。例如:JDBC 驱动,项⽬代码只需要 jdk 提供的 jdbc 接⼝,只有在执⾏测试和运⾏项⽬的时候才需要实现 jdbc 的功能。

接下来我们举⼏个例⼦在⼯程中实际去理解:

test 依赖和 compile 依赖的区别:

⾸先我们在 pom.xml ⽂件中配置,Junit 的 test 依赖

在这里插入图片描述

我们在主程序中去导⼊ Junit 的包,然后进⾏ mvn -compile 编译,很明显,test 范围的在主程序中⽆效,故编译会报错。我们在 src/main/java 包下新建 MavenTest.java,并导⼊ Junit 包

在这里插入图片描述

然后执⾏ mvn -compile 操作,如下图报错信息:

在这里插入图片描述

我们将 Junit 的依赖范围改为 compile,然后执⾏ mvn -compile

在这里插入图片描述

发现 mvn -compile 没有报错了。

在这里插入图片描述

5)依赖的传递

⽐如我们创建三个 Maven ⼯程,maven-first,maven-second 以及 maven-third,⽽ third 依赖于second,second ⼜依赖于 first,那么我们说 second 是 third 的第⼀直接依赖,first 是 second 的第⼆直接依赖。⽽ first 是 third 的间接依赖。

在这里插入图片描述

依赖之间的传递如下图:第⼀列表示第⼀直接依赖,第⼀⾏表示第⼆直接依赖

在这里插入图片描述

总结
  • 当第⼆依赖的范围是 compile 的时候,传递性依赖的范围与第⼀直接依赖的范围⼀致。
  • 当第⼆直接依赖的范围是 test 的时候,依赖不会得以传递。
  • 当第⼆依赖的范围是 provided 的时候,只传递第⼀直接依赖范围也为 provided 的依赖,且传递性依赖的范围同样为 provided;
  • 当第⼆直接依赖的范围是 runtime 的时候,传递性依赖的范围与第⼀直接依赖的范围⼀致,但 compile 例外,此时传递的依赖范围为 runtime;

6)依赖的排除

如果我们在当前⼯程中引⼊了⼀个依赖是 A,⽽ A ⼜依赖了 B,那么 Maven 会⾃动将 A 依赖的 B 引⼊当前⼯程,但是个别情况下 B 有可能是⼀个不稳定版,或对当前⼯程有不良影响。这时我们可以在引⼊ A 的时候将 B 排除。

⽐如:我们在Maven_first 中添加 spring-core,maven 会⾃动将 commons-logging添加进来,那么由于Maven_second 是依赖 Maven_first 的,那么 Maven_second 中将存在 spring-core(⾃带了commons-logging),这时候我们不想要 commons-logging,那该怎么办呢?我们上⾯第⼆⼤点提到了:

exclusions:⽤来排除传递性依赖

Maven_first 的 pom.xml ⽂件

在这里插入图片描述

由于 Maven_second 依赖 Maven_second,故 Maven_second 存在 spring-core 包在这里插入图片描述

如何排除呢?我们在 Maven_second 的 pom.xml ⽂件中添加如下代码:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lybWNavd-1609915741721)(https://i.loli.net/2021/01/03/1OYW9LqdlXgAZpr.png)]

再次查看⼯程:Maven_second 的 commons-logging 已经移除了

在这里插入图片描述

7)依赖的冲突

在 maven 中存在两种冲突⽅式:

  • ⼀种是跨 pom ⽂件的冲突。
  • ⼀种是同⼀个 pom ⽂件中的冲突。

跨 pom ⽂件,路径最短者优先。

⽐如我们在 Maven_first 中的 Junit 是4.9版本的,Maven_second 中的 Junit 是4.8版本的,那么Maven_third 中的 Junit 将会是那个版本呢?

在这里插入图片描述

由上图我们可以看出,由于 Maven_second 是 Maven_third 的直接依赖,明显相⽐于 Maven_first 路径要短,所以 Maven_third 的 Junit 版本与 Maven_second 保持⼀致

同⼀个pom.xml ⽂件,先申明者优先。

在这里插入图片描述

Maven_second

8)可选依赖

Optional 标签标示该依赖是否可选,默认是 false。可以理解为,如果为 true,则表示该依赖不会传递下去,如果为false,则会传递下去。

在这里插入图片描述
我们是在 Maven_second 的 pom ⽂件中设定 Junit 不可传递,那么Maven_third ⼯程中将不会有来⾃Maven_second 的 Junit 的传递。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值