Maven scope 其value有如下值
- compile
也就是编译,这个属性也是引用jar包的一个默认属性。
如下lombok这个jar包在我们自己的项目中引用后,不论是编译,测试,运行,打包。maven都是需要加载它的。ependency> <groupId>com.wang.ming</groupId> <artifactId>project-a</artifactId> <version>1.2</version> <scope>compile</scope> </dependency>
- provided
<dependency> <groupId>com.wang.ming</groupId> <artifactId>project-a</artifactId> <version>1.2</version> <scope>provided</scope> </dependency>
如上: provided 只是在编译和测试时使用,但是在运行和打包,maven是不会加载的,同时该jar包也不能参与依赖传递。如Servlet-api,这个jar包在编译的时候我们程序是需要调用它的,但是在运行的时候我们的程序又会被放到专门的tomcat容器中,所以编译的时引用的的Servlet-api,在运行时又不需要了,它使用tomcat中的就可以了,没必要在重复引用,导致冲突等问题。
E.g.假设当前有一个project-2b它引入了如上的project-a的1.2版本,同时scope为provided
1) 编译为Y: 当我们使用maven编译当前项目project-2b时,其编译是能够通过的。
2) 测试为Y: 如果我们的单元测试里面需要使用到project-a, 测试也是能够跑成功的,因为maven在我们跑测试代码的时候是会提前帮我们引入project-a的。
3) 运行为N: 当我们去运行当前项目project-2b是我们会发现项目直接run是不成功的,它会报错java.lang.NoClassDefFoundError 找不到被project-2b项目使用的project-a的class文件。因为我们给到当前项目project-2b的信息就是,我只是在编译的时候需要使用到project-a,运行的时候我不使用当前引用的project-a了,到时候在运行的环境容器里面,容器会给我们提供。
4) 打包为N: 这里需要注意以下打包为N,不是说打包不能打成功,因为项目是可以编译通过的,所以打包也是可以打成功的。
那么这里的打包为N代表什么呢?
如我们打包project-2b项目时以provided的方式引用的project-a,project-a项目是不会被打包插件打入到2b的jar中的。
那么就带来一个问题如果存在一个项目project-3c, 3c需要依赖2b,那么3c就必须自己引入project-a项目才能够使用2b关联到a的代码。如果3c不单独在引入project-a或者是不能从其他jar包继承到project-a,3c项目的运行就会报错的,找不到a项目相关的class。
5) 依赖传递为N: 这里的依赖传递为N,其实原理同4), 也就是2b中依赖的project-a项目是不能传递地3c项目的。
compile 和 provided的传递性对比
图一:项目依赖关系 图二:compile 图三,四:provided - runtime
像JDBC驱动一样,我们测程在编译阶段是不会直接使用它的(根据不同的DB有不同的驱动,所以java编译时其实只是编译了接口,编译时java程序不必知道具体的JDBC实例),如数据库连接池等都是我们的程序启动和驱动都启动后,才使用的驱动链接池等资源。 - import
具体参考另外一篇博文
Maven dependencyManagement的作用_TGO-Ming的博客-CSDN博客
- system
从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。
- test
test没什么好说的,就是单元测试使用的,值得注意的是它虽然不参与打包,但是根据打包插件的不同,install的时候有的插件还是会去跑test的,确保test都能跑过。