<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<scope></scope> :这个标签的意思就是当前插件依赖的范围 在开发中我们把第三方 jar 放入到 classpath 中,就能够调用第三方的类和方法。 maven 有 3 中 classpath 分别是 :
编译
测试
运行
compile 默认的范围,编译测试运行都有效。
provided 编译和测试时有效,最后是在运行的时候不会被加入。官方举了一个例子。比如在 JavaEE web 项目中我们需要使用 servlet 的 API,但是呢 Tomcat 中已经提供这个 jar,我们在编译和测试的时候需要使用这个 api,但是部署到 tomcat 的时候,如果还加入 servlet 构建就会产生冲突,这个时候就可以使用 provided。
runtime 在测试和运行时有效。
test 在测试时有效。
system 与本机系统相关联,可移植性差。编译和测试时有效。
import 导入的范围,它只在使用 dependencyManagement 中,表示从其他 pom 中导入 dependecy 的配置
假如有 Maven 项目 A,项目 B 依赖 A,项目 C 依赖 B。那么我们可以说 C 依赖 A。也就是说,依赖的关系为:C—>B—>A。 那么我们执行项目 C 时,会自动把 B、A 都下载导入到 C 项目的 jar 包文件夹中。 这就是依赖的传递性。
如上,C—>B—>A。加入现在不想执行 C 时把 A 下载进来,那么我们可以用 <exclusions>标签。
<dependencies>
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>0.0.1</version>
<exclusions>
<exclusion>
<!--被排除的依赖包坐标-->
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>0.0.1</version>
</exclusion>
</exclusions>
</dependency>
</dependencies>
- 依赖是使用 Maven 坐标来定位的,而 Maven 坐标主要由 GAV(groupId, artifactId, version)构成。如果两个相同的依赖包,如果 groupId, artifactId, version 不同,那么 maven 也认为这两个是不同的。
- 依赖会传递,A 依赖了 B,B 依赖了 C,那么 A 的依赖中就会出现 B 和 C。
- Maven 对同一个 groupId, artifactId 的冲突仲裁,不是以 version 越大越保留,而是依赖路径越短越优先,然后进行保留。
- 依赖的 scope 会影响依赖的影响范围。
把这两个 jar 分别放到 A、B 两个项目中。C—>A—>B
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
依赖冲突:一个项目 A,通过不同依赖传递路径依赖于 X,若在不同路径下传递过来的 X 版本不同,那么 A 应该导入哪个版本的 X 包呢? 冲突解决方案:
1:如果依赖路径的长度不同,则“短路优先”:
A—>B—>C—>D—>E—>X(version 0.0.1) A—>F—>X(version 0.0.2) 则 A 依赖于 X(version 0.0.2)。
2:依赖路径长度相同情况下,则“先声明优先”:
A—>E—>X(version 0.0.1) A—>F—>X(version 0.0.2) 则在项目 A 的<depencies></depencies>中,E、F 那个在先则 A 依赖哪条路径的 X。