依赖
引入依赖
当 项目A 用到了 某jarB包中的某些类时,A 就对 B 产生了依赖。那么如何在项目 中以依赖的方式引入一个我们需要的 jar 包呢?
比如项目A依赖了junit,则可以按如下方式引入依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
排除依赖
如项目A 依赖了guava,同时项目B也依赖了项目A,这时项目B不需要使用传递过来的guava类库,可以排除掉
<dependency>
<groupId>com.wojiushiwo</groupId>
<artifactId>project-a</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
依赖的范围
大家注意到上面的依赖信息中除了目标 jar 包的坐标还有一个 scope 设置,这是依赖的范围。依赖的范 围有几个可选值,我们用得到的是:compile(默认)、test、provided 三个。
以图表来展示三者的不同
complie | test | provided | |
主程序 | ✅ | ❌ | ✅ |
测试程序 | ✅ | ✅ | ✅ |
参与打包 | ✅ | ❌ | ❌ |
参与部署 | ✅ | ❌ | ❌ |
举例 | 如guava、mybatis | 如junit | 如lombok、mapconstruct |
图表说明:
如test范围依赖,对主程序无效、对测试程序有效、不参与打包、不参与部署。
依赖的传递性
如项目A 依赖了guava,同时项目B也依赖了项目A,因而项目B也传递依赖了guava。
但是 非compile范围的依赖不能传递,如项目A依赖了junit,虽然项目B依赖了项目A,但是项目B依赖不到junit,所以如果有需要,项目B就需要重新依赖junit
依赖的原则
路径最短者优先依赖
上例中项目C依赖项目B,项目B依赖项目A。而且每个项目都依赖了不同版本的guava。
那么对于项目C而言,最终使用了传递归来的guava-28.3-jre 这个jar。原因是项目C到项目B的依赖路径要小于项目C到项目A的依赖路径。
路径相同者先声明者优先依赖
上例中项目C依赖项目B,同时项目C依赖项目A。而且项目A、B都依赖了不同版本的guava,那么项目C使用什么版本的guava则取决于项目A、项目B的声明顺序。如
<dependency>
<groupId>com.wojiushiwo</groupId>
<artifactId>project-a</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.wojiushiwo</groupId>
<artifactId>project-b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
如上例中先声明项目A再声明项目B,那么使用guava-28.2-jre
反之使用guava-28.3-jre