Maven依赖作用域和依赖传递的使用

 更新时间:2023年06月02日 08:57:35   作者:守望时空33  
本文主要介绍了Maven依赖作用域和依赖传递的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在Java项目开发中,Maven是我们最常用的依赖管理和构建工具了!我们常常通过添加dependency节点,就能够很方便地加入依赖,而不需要我们自己去手动下载jar文件并引入。

今天主要是来总结一下在Maven中依赖的作用域和传递。

1,依赖作用域

通过在每个dependency中设定scope字段,即可声明其作用域,例如:

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.28</version>
	<!-- 声明作用域 -->
	<scope>provided</scope>
</dependency>

上面我们就设定了lombok这个依赖的作用域为provided

常用的作用域字段值及其意义如下:

  • compile 这是默认scope(即你不写scope字段的话,这个依赖作用域就是compile),表示依赖在编译测试运行时都是可用的,并且会参与项目的打包过程,该依赖会传递给依赖该模块的其他模块
  • provided 表示依赖在编译测试时是可用的,但该依赖不会参与程序运行阶段,即程序运行时无法调用该依赖中的类,它不会参与项目的打包过程,也不会传递给其他模块
  • runtime 表示依赖仅在运行时是可用的,但在编译和测试时不需要,它会传递给依赖该模块的其他模块,但不会参与项目的打包过程
  • test 表示依赖只在测试运行时使用,不会参与项目的打包过程,也不会传递给其他模块

可见一个Maven项目,从编译到运行会经历三个阶段:编译 → 测试 → 运行

不同作用域在三个阶段的可见性如下表:

编译时可用测试时可用运行时可用
compile
providedx
runtimex
testxx

2,作用域和打包

我们常常会使用maven-assembly-plugin插件,让我们在打包的时候将所有的依赖都打包至最后的jar文件中,使得jar文件可以直接运行。

不过真的是所有的依赖都会被打包到最后的jar中吗?

其实并不是,在使用maven-assembly-plugin插件插件时,默认只有scopecompileruntime的依赖才会被包含在最终的结果中

因此,为了减小最终jar的大小,我们应当将运行时不需要的依赖设置为provided或者test,当然这也是根据用途选择。

例如lombok依赖会在编译的时候生成gettersetter的代码,但是运行的时候这个依赖就不需要了,因此它常常被设定为provided

但是在Spring Boot开发中就不一样了,Spring Boot工程中,使用的是spring-boot-maven-plugin,这个插件也能完成同样的目的,即打包时将所有的依赖全部打包到一个jar中,但是这个插件会将所有的依赖都打包进去,无论其scope是什么。

不过,我们可以在这个插件中进行配置,声明打包时需要排除的依赖,例如:

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<configuration>
		<excludes>
			<!-- 打包时排除lombok依赖 -->
			<exclude>
				<groupId>org.projectlombok</groupId>
				<artifactId>lombok</artifactId>
			</exclude>
		</excludes>
	</configuration>
</plugin>

3,依赖的传递

事实上,在Maven中,依赖也是会传递的,我们先创建一个名为first的项目,并引入lombok依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<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">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.gitee.swsk33</groupId>
	<artifactId>first</artifactId>
	<version>1.0.0</version>
	<properties>
		<java.version>17</java.version>
		<maven.compiler.source>${java.version}</maven.compiler.source>
		<maven.compiler.target>${java.version}</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<!-- 引入lombok依赖 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.28</version>
		</dependency>
	</dependencies>
</project>

这是项目firstpom.xml文件,其groupIdcom.gitee.swsk33,其artifactIdfirst,其版本为1.0.0,现在在其工程目录下执行mvn clean install安装至本地仓库使得待会可以引用它。

现在在新建项目second,并引用上述的first作为依赖,如下:

<?xml version="1.0" encoding="UTF-8"?>
<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">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.gitee.swsk33</groupId>
	<artifactId>second</artifactId>
	<version>1.0.0</version>
	<properties>
		<java.version>17</java.version>
		<maven.compiler.source>${java.version}</maven.compiler.source>
		<maven.compiler.target>${java.version}</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<!-- 引用first项目 -->
		<dependency>
			<groupId>com.gitee.swsk33</groupId>
			<artifactId>first</artifactId>
			<version>1.0.0</version>
		</dependency>
	</dependencies>
</project>

好的,现在展开IDEA左侧栏的外部库部分,看看second项目的依赖:

image.png

可见second项目仅仅是引入了first项目,但为什么外部库中包含了lombok依赖呢?这是因为first依赖lombok,而second依赖first时,lombok也被传递给了second

image.png

同样地,如果现在又有一个项目third依赖second呢?那么third也会间接依赖lombok,也可以使用lombok中的类。

当然,依赖并不总是会传递的,有下列因素会影响依赖传递。

(1) scope作用域

scope不仅仅代表这个依赖的作用域,也会影响依赖的传递,只有scopecompileruntime的依赖是会传递的

假设现在把上述first项目中的lombok依赖scope改成provided或者test,然后重新执行mvn clean install,你就会发现在second的依赖中,就看不到lombok了!

(2) optional字段

除了scope之外,还可以设定依赖的optional字段,当设定为true时代表这个依赖是可选的,那么这时无论其scope是什么,这个依赖都不会传递。默认情况下,即不声明依赖的optional字段时,它的值是false

现在将first中的lombok依赖的optional字段声明为true

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.28</version>
	<optional>true</optional>
</dependency>

然后重新mvn clean install,再次打开second项目,你就会发现lombok依赖就没有传递过来了!

image.png

所以如果在制作外部库需要其他人引用的时候,我们可以将一些仅仅是外部库需要使用但是其它项目不一定要使用的依赖的optional设定为true,避免其他开发者引入你的外部库时发生依赖冲突。

到此这篇关于Maven依赖作用域和依赖传递的使用的文章就介绍到这了,更多相关Maven依赖作用域和依赖传递内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决Error occurred during initialization of VM Java虚拟机初始化失败问题

    解决Error occurred during initialization o

    这篇文章主要介绍了解决Error occurred during initialization of VM Java虚拟机初始化失败问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • Java中的@Accessors使用详解

    Java中的@Accessors使用详解

    这篇文章主要介绍了Java中的@Accessors使用详解,@RequiredArgsConstructor是Lombok的一个注解,简化了我们对setter和getter方法操作,它可以作用在类上,也可以作用在类的单个属性上,需要的朋友可以参考下
    2024-01-01
  • SSH框架网上商城项目第16战之Hibernate二级缓存处理首页热门显示

    SSH框架网上商城项目第16战之Hibernate二级缓存处理首页热门显示

    这篇文章主要介绍了SSH框架网上商城项目第16战之Hibernate的二级缓存处理首页的热门显示,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • java学生信息管理系统源代码

    java学生信息管理系统源代码

    这篇文章主要为大家详细介绍了java学生信息管理系统源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Java 栈和队列的相互转换详解

    Java 栈和队列的相互转换详解

    栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 "一对一" 的数据,但由于它们比较特殊,因此将其单独作为一章,做重点讲解
    2022-02-02
  • 带你了解mybatis如何实现读写分离

    带你了解mybatis如何实现读写分离

    本篇文章主要介绍了MyBatis实现数据读写分离的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能给你带来帮助
    2021-08-08
  • SpringSecurity抛出异常但AccessDeniedHandler不生效的解决

    SpringSecurity抛出异常但AccessDeniedHandler不生效的解决

    本文主要介绍了SpringSecurity抛出异常但AccessDeniedHandler不生效的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • Java Json字符串的双引号(

    Java Json字符串的双引号("")括号如何去掉

    这篇文章主要介绍了Java Json字符串的双引号("")括号如何去掉?具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java微信公众号推送模版消息的步骤示例详解

    Java微信公众号推送模版消息的步骤示例详解

    模板消息是一种向用户发送通知的服务,广泛用于订单状态更新、服务提醒等场景,下面,我将详细介绍如何使用Java结合微信官方提供的API来实现模板消息的推送,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • Spring Core核心类库的功能与应用实践分析

    Spring Core核心类库的功能与应用实践分析

    本文详细介绍了SpringCore核心类库的功能、应用实践和底层原理,SpringCore提供了控制反转(IOC)、依赖注入(DI)、Bean管理以及JNDI、定时任务等企业级功能,文章通过多个Java示例展示了SpringCore的应用,感兴趣的朋友跟随小编一起看看吧
    2024-12-12

最新评论