一、依赖传递(Scope取值)
maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。在maven中,scope包含如下的取值:
-
compile(编译范围)
compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。
编译范围依赖在所有的classpath中可用,同时它们也会被打包。
比如:A工程依赖B工程,而B工程中依赖a.jar(scope="compile"),则在A工程中也会自动引入a.jar,这就是scope="compile"的依赖传递。
-
provided(已提供范围)
provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用。
开发时使用,但是运行的时候不需要,因为容器(tomcat)有,如果再引入则会造成包冲突,但是在工程中又不得不引入(不引入则无法开发)
比如:web开发中使用的HttpServlet这个jar包,开发的时候必须使用,但是把项目发布到tomcat时候是不能把这个包也引入的(tomcat已经有这个包,再引入可能会冲突)
这时候把这个HttpServlet包的scope="provided",这个当工程被打包的时候这个HttpServlet包不会被打包。
-
runtime(运行时范围)
runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。
比如,你可能在编译的时候只需要JDBC API JAR,
而只有在运行的时候才需要JDBC驱动实现。
-
test(测试范围)
test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。 测试范围依赖在之前的中介绍过。
-
compile/runtime:会进行依赖传递
-
provided/test: 不进行依赖传递。
二、案例
- A->B(compile) 第一关系: a依赖b compile
- B->C(compile) 第二关系: b依赖c compile
- 当在A中配置
<dependency> <groupId>com.B</groupId> <artifactId>B</artifactId> <version>1.0</version> </dependency>
则会自动导入c中的包。关系传递如下表:
第一 第二 |
compile |
test |
provided |
runtime |
compile |
compile |
- |
- |
runtime |
test |
test |
- |
- |
test |
provided |
provided |
- |
provided |
provided |
runtime |
runtime |
- |
- |
runtime |
-
依赖冲突的调节
A->B->C->X(1.0)
A->D->X(2.0)
由于只能引入一个版本的包,此时Maven按照最短路径选择导入x(2.0)
A->B->X(1.0)
A->D->X(2.0)
路径长度一致,则优先选择第一个,此时导入x(1.0)
-
排除依赖
A:排除依赖管理
-
案例
maven01/pom.xml :
<dependencies> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven02</artifactId> <version>0.0.1-SNAPSHOT</version> <exclusions> <exclusion> <groupId>com.shyroke</groupId> <artifactId>maven01</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven02_1</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
可知,maven01依赖maven02和maven02_1,其中maven02和maven02_1分别依赖:
maven02/pom.xml:
<dependencies> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven01</artifactId> <version>3.0.1-SNAPSHOT</version> </dependency> </dependencies>
maven02_1/pom.xml:
<dependencies> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven01</artifactId> <version>1.0.1-SNAPSHOT</version> </dependency> </dependencies>
结果:
如果没有用<exclusions>排除依赖,那么这里引用的是maven02/pom.xml中的依赖(路径长度一致,则优先选择第一个)
B、在pom.xml中指定具体引用的版本。
<dependencies> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven02</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven02_1</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.shyroke</groupId> <artifactId>maven01</artifactId> <version>2.0.1-SNAPSHOT</version> </dependency> </dependencies>
结果:
-
依赖关系的查看
cmd进入工程根目录,执行 mvn dependency:tree会列出依赖关系树及各依赖关系
mvn dependency:analyze 分析依赖关系
- 可以将Spring的版本定义为一个变量。然后在dependency中引用变量的值。
<properties> <spring-version>4.3.0.RELEASE</spring-version> </properties>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring-version}</version> </dependency>