这一篇文章应该是全网讲解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的打包。
二、依赖传递代码演示
如下是一个父子聚合工程,不设置optional的情况:
打成jar包后,我们可以将jar解压,解压后在BOOT-INF的lib下存放着所能使用的依赖jar包,在这里可以看到hutool。
设置optional为true的情况:
没有那也就意味着不能访问hutool的类了,想要访问只能在当前项目再次引用了。
我有点好奇,既然这里看不到那么他究竟会参与打包吗?假如不参与打包,我们download工程调用common中的方法,然后common中的方法又使用了hutool工具类,那能否访问成功?接下来我们来一点一点的印证!
1.设置为true的时候是否会参与download工程的打包?
答:他是不会参与download的打包的,打成jar包后,我们可以将jar解压,解压后在BOOT-INF的lib下存放着所能使用的依赖jar包。
2.假如不参与打包,我们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,那当前项目就不能用。
三、是否会影响父子工程之间的依赖继承呢?
假如我在聚合工程的父pom依赖当中使用optional为true,那子工程会继承吗?接下来进行演示。
注:在父工程设置optional为true,并不会影响子工程继承该依赖。
四、总结
- 将依赖设置为true不仅代表着依赖不会传递,就连打包的时候都不会将该jar打包进去,一旦使用到调用该jar包的方法就会异常。
- 在父工程设置optional为true,并不会影响子工程继承该依赖。
- 不管是当前项目引用的,还是间接引用的,所有依赖jar包都存放在jar解压后的
BOOT-INF下/jar
目录下,只要这下面没有jar,那当前项目就不能用。
什么时候将optional设置为true?
就拿hutool工具类来说,如下图:你想用他的某些工具类,他还让你引用一些第三方的依赖,为什么他不直接引用到自己的项目?
实际上hutool他肯定是引用了的,如果不引用他的项目可能连编译都编译不过,更别提打包给我们用了,他是将这个依赖设置为了true,假如谁用到了这块的功能,谁自己引入这个依赖。这样可以规避掉一些没有用到这块功能但是却引入了没有用的jar包。