Maven中optional标签详解

文章详细探讨了Maven中optional依赖的设置对项目构建和依赖传递的影响。通过代码演示,说明了optional为true时,依赖不会被传递,不会参与打包,且在调用时会导致找不到相关类。同时,文章讨论了父子工程间的依赖继承问题,即使在父工程设置optional为true,也不会影响子工程继承该依赖。最后,作者指出将optional设为true可以避免引入不必要的jar包。
摘要由CSDN通过智能技术生成

这一篇文章应该是全网讲解optional最细致的,因为我都是拿我自己的试验来证明,从试验当中也发现了很多出乎意外的知识!感兴趣的跟着小编一块来学习呀!

一、前言

<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.18</version>
  <optional>true</optional>
</dependency>

optional表示是否会传递依赖,有两个可填值(假如不声明optional标签,默认就是false):

  • false: 传递依赖
  • true:不传递依赖

举例:A引用了B的依赖,而B又引用了C依赖。

  • 假如B引用C依赖的时候没有设置optional,那么A是可以使用C依赖的。
  • 假如B引用C依赖的时候将optional标签设置为了true,那么在A当中就无法使用C依赖相关的方法,并且A调用B依赖的方法,而B依赖方法使用到了C,这时候会报找不到C依赖下的类,因为C不参与A的打包。

二、依赖传递代码演示

(1)如下是一个父子聚合工程,不设置optional的情况:

打成jar包后,我们可以将jar解压,解压后在BOOT-INF的lib下存放着所能使用的依赖jar包,在这里可以看到hutool。

(2)设置optional为true的情况:

没有那也就意味着我再download工程不能访问hutool的类了,想要访问只能在当前项目再次引用了。

(3)我有点好奇,既然这里看不到那么他究竟会参与打包吗?假如不参与打包,我们download工程调用common中的方法,然后common中的方法又使用了hutool工具类,那能否访问成功?接下来我们来一点一点的印证!

设置为true的时候是否会参与download工程的打包?

答:他是不会参与download的打包的,打成jar包后,我们可以将jar解压,解压后在BOOT-INF的lib下存放着所能使用的依赖jar包。

假如不参与打包,我们download工程调用common中的方法,然后common中的方法又使用了hutool工具类,那能否访问成功?

答:不能访问成功,直接会报找不到hutool的类

我解压common包发现连BOOT-INF都没有,并不是只有common的jar包解压没有,而是所有的都没有。

我一直以为common包引用了hutool,那么解压common包就应该在BOOT-INF下的jar中看到hutool.jar,其实不是的,maven打包会将所有依赖关系全部放到当前项目的BOOT-INF/jar目录下

为此我专门在common当中写了一个方法,然后使用到了hutool当中的类。

然后我又在download工程下写了一个接口,让这个接口访问common包下test方法。

紧接着启动项目,启动download项目并没有异常,只要访问common包当中方法带有hutool相关的都报异常,说找不到hutool的包。因为我们刚刚也看过了,确实是没有这个jar包。

从而也证明了,不管是当前项目引用的,还是间接引用的,jar包都存放在BOOT-INF下/jar目录下,只要这下面没有jar,那当前项目就不能用。

三、为啥common的jar包下没有BOOT-INF呢?

在download下的BOOT-INF/lib下的common包解压后没有BOOT-INF我可以理解,因为所有的jar包都没有。但是为什么target当中的jar包解压后也没有,而download却有。他两个唯一的区别就是,一个是有main函数的web工程,一个是连main方法都没有的而且也没有打包插件。

我的父工程继承了spring-boot-starter-parent

而spring-boot-starter-parent当中对打包插件做了如下配置,也就意味着子工程一旦声明该插件就会遵循如下配置:

于是我在common包下添加了打包插件。注意使用打包插件意味着打出来的jar是一个可以直接执行的jar,因此必须要声明main函数,否则会打包异常的。

并且新增了一个主函数

于是再次打包,这时候会发现jar包大小已经发生了变化。解压后会发现他已经存在BOOT-INF了。

但是诡异的一幕发生了,download引入了common包,并且download调用了common包下的方法,直接就mvn install 不通过了。说在仓库找不到包。

但是在仓库当中实际上是存在这个包的。那也就是证明项目不能引用可执行jar。

于是我又把common的打包插件给去掉之后mvn install可以成功了。因此也证明了假如我们要封装自己的jar,一定不要使用打包插件。一旦使用插件就会变成了可执行jar,可执行jar是不可以被别的项目所引用的。

四、是否会影响父子工程之间的依赖继承呢?

假如我在聚合工程的父pom依赖当中使用optional为true,那子工程会继承吗?接下来进行演示。

注:在父工程设置optional为true,并不会影响子工程继承该依赖。

五、总结

  1. 将依赖设置为true不仅代表着依赖不会传递,就连打包的时候都不会将该jar打包进去,一旦使用到调用该jar包的方法就会异常。
  2. 在父工程设置optional为true,并不会影响子工程继承该依赖。
  3. 不管是当前项目引用的,还是间接引用的,所有依赖jar包都存放在jar解压后的BOOT-INF下/jar目录下,只要这下面没有jar,那当前项目就不能用。

什么时候将optional设置为true?

就拿hutool工具类来说,如下图:你想用他的某些工具类,他还让你引用一些第三方的依赖,为什么他不直接引用到自己的项目?

实际上hutool他肯定是引用了的,如果不引用他的项目可能连编译都编译不过,更别提打包给我们用了,他是将这个依赖设置为了true,假如谁用到了这块的功能,谁自己引入这个依赖。这样可以规避掉一些没有用到这块功能但是却引入了没有用的jar包。

Maven是一种流行的项目管理工具,它使用XML格式的配置文件来定义项目的构建和依赖关系。其Maven的settings.xml文件是用来配置Maven的全局设置的。 settings.xml文件有几个重要的标签需要详细解释: 1. <localRepository>标签:用于指定本地仓库的路径。本地仓库是一个存储项目依赖包的地方,当Maven构建项目时,它会从本地仓库查找依赖包,如果没有找到,则从远程仓库下载。通过指定<localRepository>标签,可以更改本地仓库的默认路径。 2. <mirrors>标签:用于配置镜像仓库。Maven央仓库通常是项目依赖包下载的默认来源。但由于某些原因,我们可能无法直接连接到央仓库,或者下载速度很慢。使用<mirrors>标签,可以配置镜像仓库,从而加快依赖包的下载速度。 3. <profiles>标签:用于配置不同环境下的构建参数。在不同的开发环境,可能需要使用不同的构建配置。通过<profiles>标签,可以定义不同的构建配置,并在构建时选择相应的配置。这样可以保证在不同环境的构建一致性。 4. <servers>标签:用于配置Maven的认证信息。有些私有仓库可能需要认证才能访问。通过<servers>标签,可以配置私有仓库的URL、用户名和密码,以便Maven能够访问私有仓库。 5. <proxies>标签:用于配置代理服务器。如果项目所在的网络环境需要通过代理服务器才能访问外部网络资源,可以使用<proxies>标签配置代理服务器的相关信息,以便Maven能够访问远程仓库。 这些标签是settings.xml文件的主要配置项,通过合理设置这些标签,可以灵活地配置Maven的工作方式,并满足项目构建和依赖管理的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪 咖@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值