10人参与 • 2025-06-11 • Java
我们在从网上下载需要的依赖的时候,不同的jar包与jar包之间有依赖关系,且不同的版本之间也需要注意是否有冲突,使用maven就可以帮助我们去管理和自动解决软件包依赖问题,我们只需要关注我们需要的jar包和版本即可。
通过定义 pom 文件,maven 能够自动解析项目的依赖关系,并通过 maven 仓库自动下载和管理依赖,从而避免了手动下载和管理依赖的繁琐工作和可能引发的版本冲突问题。
总之,maven 的依赖管理使得软件包依赖的管理,和使用更加智能和方便,简化了开发过程中的工作,并提高了软件质量和可维护性。
位置:pom.xml
<!-- 模型版本 --> <modelversion>4.0.0</modelversion> <!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径: /com/companyname/project-group --> <groupid>com.companyname.project-group</groupid> <!-- 项目的唯一id,一个groupid下面可能多个项目,就是靠artifactid来区分的 --> <artifactid>project</artifactid> <!-- 版本号 --> <version>1.0.0</version> <!--打包方式 默认:jar jar指的是普通的java项目打包方式, 项目打成jar包 war指的是web项目打包方式,项目打成war包 pom不会将项目打包,这个项目作为父工程,被其他工程聚合或者继承 --> <packaging>jar/pom/war</packaging>
位置:pom.xml
<!-- 通过编写依赖jar包的gav必要属性,引入第三方依赖! scope属性是可选的,可以指定依赖生效范围! 依赖信息查询方式: 1. maven仓库信息官网 https://mvnrepository.com/ 2. mavensearch插件搜索 --> <dependencies> <!-- 引入具体的依赖包 --> <dependency> <groupid>log4j</groupid> <artifactid>log4j</artifactid> <version>1.2.17</version> <!-- 依赖范围 --> <scope>runtime</scope> </dependency> </dependencies>
maven中,有个<properties>标签,该标签用于定义项目构建过程中可以使用的属性。
通过在properties标签中自定义管理依赖的版本号,方便我们统一管理各种依赖的版本,当需要升级或更改依赖版本时,只需在<properties>标签中修改一次,而不需要逐个查找并替换pom文件中的每个依赖标签,这大大提高了维护的效率。
<properties> <!-- 通过maven规定的固定的key,配置maven的参数:--> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceencoding>utf-8</project.build.sourceencoding> <project.reporting.outputencoding>utf-8</project.reporting.outputencoding> <!--声明版本:命名随便,内部制定版本号即可--> <junit.version>5.9.2</junit.version> </properties> <dependencies> <dependency> <groupid>org.junit.jupiter</groupid> <artifactid>junit-jupiter-api</artifactid> <!--引用properties声明版本 --> <version>${junit.version}</version> <!--引用依赖的运行范围(尽量不要更改) --> <scope>test</scope> </dependency> </dependencies>
通过设置坐标的依赖范围(scope),可以设置对应jar包的作用范围(三种classpath):编译环境(在main包下)、测试环境(在test包下)、运行环境(打包后的jar包或war包是否有对应的依赖包)。
scope标签中的依赖范围可以修改,但是不建议,在https://mvnrepository.com/中搜索出来的依赖范围是什么,就是什么,尽量不要修改!
依赖范围 | 描述 |
---|---|
compile | 编译依赖范围,scope 元素的缺省值,即如果下载的依赖没有scope标签,默认是compile范围。使用此依赖范围的 maven 依赖,对于三种 classpath 均有效,即该 maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。 |
test | 测试依赖范围。使用此依赖范围的 maven 依赖,只对测试 classpath 有效。例如,junit 依赖只有在测试阶段才需要。 |
provided | 已提供依赖范围。使用此依赖范围的 maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 maven 重复引入该依赖。 |
runtime | 运行时依赖范围。使用此依赖范围的 maven 依赖,只对测试 classpath、运行 classpath 有效。例如,jdbc 驱动实现依赖,其在编译时只需 jdk 提供的 jdbc 接口即可,只有测试、运行阶段才需要实现了 jdbc 接口的驱动。 |
system | 系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 maven 仓库的本地依赖,通过依赖元素 dependency 中的 systempath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。 |
import | 导入依赖范围,该依赖范围只能与 dependencymanagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencymanagement 的配置导入合并到当前 pom.xml 的 dependencymanagement 中。 |
项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。(将一系列的原材料生产为一个产品,即打成jar包或war包的过程)
默认情况下,构建不需要额外配置,都有对应的缺省配置。当然了,我们也可以在pom.xml定制一些配置,来修改默认构建的行为和产物。
例如:
构建配置是在pom.xml / build标签中指定!
<!-- 默认的打包名称:artifactid+verson.打包方式 --> <build> <finalname>定义打包名称</finalname> </build>
使用案例:不指定打包名称默认是maven_web-1.0-snapshot.war
如果在java文件夹中添加java类,resources文件夹中添加配置文件,即默认情况下,按照maven工程结构放置的文件,会默认被编译和打包到classes文件夹下:
但是如果我们不按照要求将文件放在对应的文件夹下,又想要将文件打包到classes中,例如mybatis中有时会将用于编写sql语句的映射文件,和mapper接口都写在src/main/java下的某个包中,此时映射文件也不会被打包。
解决方案:使用resources标签,指定要打包资源的文件夹,要把哪些静态资源打包到 classes根目录下。
<build> <!--设置要打包的资源位置--> <resources> <resource> <!--设置资源所在目录--> <directory>src/main/java</directory> <includes> <!--设置包含的资源类型--> <include>**/*.xml</include> </includes> </resource> </resources> </build>
此时,不在resources文件夹下的文件也被成功打包!
dependencies标签下引入开发需要的jar包,我们可以在build/plugins/plugin标签引入插件。常用的插件:修改jdk版本、tomcat插件、mybatis分页插件、mybatis逆向工程插件等等。pom.xml文件中配置了tomcat插件,就可以省略在edit configurations中配置tomcat了。
具体步骤参考我的另一篇文章:《maven3.8.1使用tomcat8插件启动项目的方法(亲测有效)》
概念
假如有maven项目a,项目b依赖a,项目c依赖b。那么我们可以说 c依赖a。也就是说,依赖的关系为:c—>b—>a, 那么我们执行项目c时,会自动把b、a都下载导入到c项目的jar包文件夹中,这就是依赖的传递性。
作用
案例演示:
创建2个项目,maven_a和maven_b:
在maven_a的pom.xml文件中引入maven_b的坐标:
在maven_b的pom.xml文件中配置druid依赖,更新maven,发现maven_a项目中也能使用druid
使用mvn dependency:tree命令也可以查看依赖关系:
也可以使用下面的命令在文件中查看依赖关系:
mvn dependency:build-classpath > classpath.txt
在 a 依赖 b,b 依赖 c 的前提下,c 是否能够传递到 a,取决于 b 依赖 c 时使用的依赖范围以及配置:只有scope标签是compile的才能传递,test和provided依赖范围都不能传递,需要手动配置!scope标签中的依赖范围可以修改,但是不建议,在https://mvnrepository.com/中搜索出来的依赖范围是什么,就是什么,尽量不要修改!
另外,还有依赖传递的终止标签:<optional>true</optional>
若配置了optional标签,则不能传递
<dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.8</version> <optional>true</optional> </dependency>
当直接引用或者间接引用出现了相同的jar包! 这时呢,一个项目就会出现相同的重复jar包,这就算作冲突!依赖冲突避免出现重复依赖,并且终止依赖传递!
maven自动解决依赖冲突问题能力,会按照自己的原则,进行重复依赖选择。同时也提供了手动解决的冲突的方式,不过不推荐!
示例:
maven_b的pom.xml:
<dependencies> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.8</version> </dependency> </dependencies>
maven_a的pom.xml:
<dependencies> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_b</artifactid> <version>1.0-snapshot</version> </dependency> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.7</version> </dependency> </dependencies>
查看maven_a的依赖树:maven_b中的druid 1.2.8版本被排除,maven_a中使用的是druid 1.2.7
如果你的重复依赖没有置灰,把maven_a的pom.xml文件中,dependencies下的所有dependency清空,刷新后重新添加依赖,就能看到置灰的依赖了,重复依赖没有置灰是idea的显示问题。
示例:
创建项目maven_c,其pom.xml文件如下:
<dependencies> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.7</version> </dependency> </dependencies>
maven_b的pom.xml:
<dependencies> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.8</version> </dependency> </dependencies>
maven_a的pom.xml:
<dependencies> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_b</artifactid> <version>1.0-snapshot</version> </dependency> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_c</artifactid> <version>1.0-snapshot</version> </dependency> </dependencies>
查看maven_a的依赖树:maven_b先声明,就使用maven_b的druid 1.2.8版本
调换一下:
<dependencies> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_c</artifactid> <version>1.0-snapshot</version> </dependency> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_b</artifactid> <version>1.0-snapshot</version> </dependency> </dependencies>
查看maven_a的依赖树:maven_c先声明,就使用maven_c的druid 1.2.7版本
我们知道,先声明的就会被先使用,如果只想使用maven_c中的druid 1.2.7的依赖,可以手动排除依赖,使用exclusions标签,里面可以嵌套多个exclusion标签,exclusion标签中只需写明要排除的g和a坐标即可:
<dependencies> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_b</artifactid> <version>1.0-snapshot</version> <!--依赖排除--> <exclusions> <exclusion> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>com.alibaba.maven</groupid> <artifactid>maven_c</artifactid> <version>1.0-snapshot</version> </dependency> </dependencies>
查看依赖树:maven_b中的druid 1.2.8被成功排除!
maven 继承是指在 maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。
在父工程中统一管理项目中的依赖信息。
它的背景是:
它背后的需求是:
创建一个父工程——maven_parent:
<groupid>com.alibaba.maven</groupid> <artifactid>maven_parent</artifactid> <version>1.0-snapshot</version> <!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom --> <packaging>pom</packaging>
创建一个子工程——maven_son:
<!-- 使用parent标签指定当前工程的父工程 --> <parent> <!--父工程的坐标--> <artifactid>maven_parent</artifactid> <groupid>com.alibaba.maven</groupid> <version>1.0-snapshot</version> </parent> <modelversion>4.0.0</modelversion> <!-- 子工程的坐标 --> <!-- 如果子工程坐标中的groupid和version与父工程一致,那么可以省略 --> <artifactid>maven_son</artifactid>
创建好子工程maven_son后,父工程maven_parent的pom.xml文件也会发生改变:
<groupid>com.alibaba.maven</groupid> <artifactid>maven_parent</artifactid> <version>1.0-snapshot</version> <!-- 创建子工程时,选择父工程后,会在父工程中自动生成: --> <modules> <module>maven_son</module> </modules> <!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom --> <packaging>pom</packaging>
在父工程maven_parent添加依赖:
<dependencies> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.7</version> </dependency> </dependencies>
子工程会无条件继承父工程中的依赖:
甚至包括scope是test和provide的:
在使用父工程的时候,一般很少直接使用dependencies,让所有依赖直接被子工程继承,而是使用dependencymanagement来统一管理依赖:
<!-- 使用dependencymanagement标签配置对依赖的管理 --> <!-- 被管理的依赖并没有真正被引入到工程 --> <dependencymanagement> <dependencies> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.2.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> <dependency> <groupid>org.junit.jupiter</groupid> <artifactid>junit-jupiter-api</artifactid> <version>5.9.2</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupid>javax.servlet</groupid> <artifactid>javax.servlet-api</artifactid> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies> </dependencymanagement>
此时子工程中就需要手动选择需要继承父工程中的依赖:
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。 --> <!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 --> <!-- 具体来说是由父工程的dependencymanagement来决定。 --> <dependencies> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> </dependency> </dependencies>
maven 聚合是指将多个项目组织到一个父级项目中,以便一起构建和管理的机制。聚合可以帮助我们更好地管理一组相关的子项目,同时简化它们的构建和部署过程。
父项目中包含的子项目列表。
当我们对父工程进行了操作,比如package打包,里面的子工程也会进行相同的操作,提高开发效率。
<groupid>com.alibaba.maven</groupid> <artifactid>maven_parent</artifactid> <version>1.0-snapshot</version> <modules> <module>maven_son</module> <module>../maven_a</module> <module>../maven_web</module> </modules> <!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom --> <packaging>pom</packaging>
父工程执行package命令:
对应的子工程会一键打包:
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论