前言
首先二者都可以阻止依赖传递,很多人说二者只有语意上的区别,实际上还是有一些实在的区别的
准备
为了说明,我建了3个项目A,B,C,其中C依赖B,B依赖A(由于maven默认依赖是可传递的,所以C也依赖A)
依赖关系一个项目建一个类,分别是A,B,C
三个测试类其中B的代码:
public class B {
@Override
public String toString() {
return "B depends-on " + A.class; // 使用maven-a项目中的A类
}
}
然后在B对A的引用上添加两种配置,实验二者的区别
一致的效果
首先不管用哪个,C类中都无法使用A,证明二者在阻止依赖传递上的功能是一致的
当C类中调用B方法的toString(方法内部使用了A)
,如下
public class C {
public static void main(String[] args) {
System.out.println(new B().toString());
}
}
二者都会直接报错:找不到A
不同的地方
如果我们再B类中写一个main方法,并使用A类,二者的区别就出现了
public static void main(String[] args) {
System.out.println(A.class);
}
<scope>provided</..>
首先使用<scope>provided</..>,运行main方法直接报错Exception in thread "main" java.lang.NoClassDefFoundError: A
<optional>true</..>
再试<optional>true</..>,发现正常输出class A
总结
optional=true
:代表我有这个依赖,编译可以通过,并且我运行时也课时使用,但是依赖我的项目不能使用
scope=provided
:代表我有这个依赖,编译可以通过,但是运行时不能用,依赖我的项目更不能用
如果两种方式分别打包,你会发现<scope>provided</..>时项目B的target只有B.class文件,而<optional>true</..>时,target目录下同时存在B.class和A.class
所以有时候使用<scope>provided</..>
方式时想写个main方法做个小测试,会发现报错java.lang.NoClassDefFoundError:
网友评论