Maven依赖管理

打印 上一主题 下一主题

主题 1013|帖子 1013|积分 3039

本文主要记录Maven依赖管理中关于依赖传递和依赖范围的知识
Maven项目示例

创建3个maven项目,分配依赖log4j 1.2.12, 1.2.13, 1.2.14版本。
  1. <groupId>com.leo</groupId>
  2. <artifactId>project1</artifactId>
  3. <version>1.0-SNAPSHOT</version>
  4. <dependencies>
  5.         <dependency>
  6.                 <groupId>log4j</groupId>
  7.                 <artifactId>log4j</artifactId>
  8.                 <version>1.2.12</version>
  9.         </dependency>
  10. </dependencies>
  11. <groupId>com.leo</groupId>
  12. <artifactId>project2</artifactId>
  13. <version>1.0-SNAPSHOT</version>
  14. <dependencies>
  15.         <dependency>
  16.                 <groupId>log4j</groupId>
  17.                 <artifactId>log4j</artifactId>
  18.                 <version>1.2.13</version>
  19.         </dependency>
  20. </dependencies>
  21. <groupId>com.leo</groupId>
  22. <artifactId>project3</artifactId>
  23. <version>1.0-SNAPSHOT</version>
  24. <dependencies>
  25.         <dependency>
  26.                 <groupId>log4j</groupId>
  27.                 <artifactId>log4j</artifactId>
  28.                 <version>1.2.14</version>
  29.         </dependency>
  30. </dependencies>
复制代码
此时三个项目的依赖关系如图所示,三个项目分别依赖了不同版本的log4j。

依赖传递

现在我们构造这样一种情况,project3依赖log4j和junit,project2依赖log4j和project3,maven配置如下:
  1. <groupId>com.leo</groupId>
  2. <artifactId>project2</artifactId>
  3. <version>1.0-SNAPSHOT</version>
  4. <dependencies>
  5.         <dependency>
  6.                 <groupId>log4j</groupId>
  7.                 <artifactId>log4j</artifactId>
  8.                 <version>1.2.13</version>
  9.         </dependency>
  10.         <dependency>
  11.                 <groupId>com.leo</groupId>
  12.                 <artifactId>project3</artifactId>
  13.                 <version>1.0-SNAPSHOT</version>
  14.         </dependency>
  15. </dependencies>
  16. <groupId>com.leo</groupId>
  17. <artifactId>project3</artifactId>
  18. <version>1.0-SNAPSHOT</version>
  19. <dependencies>
  20.         <dependency>
  21.                 <groupId>log4j</groupId>
  22.                 <artifactId>log4j</artifactId>
  23.                 <version>1.2.14</version>
  24.         </dependency>
  25.         <dependency>
  26.                 <groupId>junit</groupId>
  27.                 <artifactId>junit</artifactId>
  28.                 <version>4.12</version>
  29.         </dependency>
  30. </dependencies>
复制代码
此时project2和project3的依赖关系如图:

此时project2的依赖关系中出现了project3以及project3所依赖的包。对于project2来说,此时不光可以使用project3,也可以使用project3所以来的junit包。
同时我们注意到,project3依赖了1.2.14版本的log4j,这与project2本身所依赖的1.2.13版本冲突了。
此时Maven会使用如下3个规则来选择哪个包生效:

  • 依赖层级浅的包会覆盖依赖层级深的包。(示例中project2的log4j 1.2.13版本的依赖层级为1,1.2.14的依赖层级为2,因此第一层的版本生效)
  • 同层依赖中,先声明的包版本生效。


  • 同pom.xml文件中,后声明的版本生效。
依赖隐藏

如果不希望别人在依赖我的包时知道我的包依赖了哪些其他的包,那么可以在引用依赖时将其标注为true,这样别人在使用这个包时,就不会看到这个包依赖的包。
  1. <groupId>com.leo</groupId>
  2. <artifactId>project2</artifactId>
  3. <version>1.0-SNAPSHOT</version>
  4. <dependencies>
  5.         <dependency>
  6.                 <groupId>log4j</groupId>
  7.                 <artifactId>log4j</artifactId>
  8.                 <version>1.2.13</version>
  9.         </dependency>
  10.         <dependency>
  11.                 <groupId>com.leo</groupId>
  12.                 <artifactId>project3</artifactId>
  13.                 <version>1.0-SNAPSHOT</version>
  14.         </dependency>
  15. </dependencies>
  16. <groupId>com.leo</groupId>
  17. <artifactId>project3</artifactId>
  18. <version>1.0-SNAPSHOT</version>
  19. <dependencies>
  20.         <dependency>
  21.                 <groupId>log4j</groupId>
  22.                 <artifactId>log4j</artifactId>
  23.                 <version>1.2.14</version>
  24.         </dependency>
  25.         <dependency>
  26.                 <groupId>junit</groupId>
  27.                 <artifactId>junit</artifactId>
  28.                 <version>4.12</version>
  29.         </dependency>
  30. </dependencies>        true       
复制代码
这样配置后,依赖关系如下图所示

可以看到在project2中是无法看到project3所依赖的junit包的。当然也就无法通过依赖传递的方式使用到junit包。
依赖屏蔽

当我们引用别人的包时,别人的包中某些依赖我们不想引入自己的项目,那我们可以使用如下方式排除间接依赖的包。
  1. <groupId>com.leo</groupId>
  2. <artifactId>project2</artifactId>
  3. <version>1.0-SNAPSHOT</version>
  4. <dependencies>
  5.         <dependency>
  6.                 <groupId>log4j</groupId>
  7.                 <artifactId>log4j</artifactId>
  8.                 <version>1.2.13</version>
  9.         </dependency>
  10.         <dependency>
  11.                 <groupId>com.leo</groupId>
  12.                 <artifactId>project3</artifactId>
  13.                 <version>1.0-SNAPSHOT</version>
  14.                
  15.                 <exclusions>
  16.                         <exclusion>
  17.                                 <groupId>log4j</groupId>
  18.                                 <artifactId>log4j</artifactId>
  19.                         </exclusion>
  20.                 </exclusions>
  21.         </dependency>
  22. </dependencies>
  23. <groupId>com.leo</groupId>
  24. <artifactId>project3</artifactId>
  25. <version>1.0-SNAPSHOT</version>
  26. <dependencies>
  27.         <dependency>
  28.                 <groupId>log4j</groupId>
  29.                 <artifactId>log4j</artifactId>
  30.                 <version>1.2.14</version>
  31.         </dependency>
  32.         <dependency>
  33.                 <groupId>junit</groupId>
  34.                 <artifactId>junit</artifactId>
  35.                 <version>4.12</version>
  36.         </dependency>
  37. </dependencies>
复制代码
如此配置后的依赖关系如图:

可以看到project2中没有引入project3所依赖的log4j。
依赖范围

引入依赖时,可以指定依赖包的生效范围
scope主代码测试代码打包范例compile(默认)YYYlog4jtestYjunitprovidedYYservlet-apiruntimeYjdbc

  • provided解释:例如,我们本地开发时使用了servlet-api 3.0版本进行调测,但当我们要把代码部署到服务器的tomcat中时,服务器的tomcat不支持3.0版本的servlet-api,它自带了自己的版本。如果我们把3.0版本打包进去,由于3.0版本会先加载,就导致在服务器的tomcat中无法运行。
  • runtime解释:jdbc平时我们在使用的时候,加载driver都是通过字符串的形式,在代码中并没有真正引用过driver的内容,因此开发时可以不用引入需要依赖的driver,只要打包时把driver打进去就行了。
依赖范围的传递性

compiletestprovidedruntimecompilecompiletestprovidedruntimetestprovidedruntimeruntimetestprovidedruntime行表示本项目所依赖的包配置的scope,列表示依赖包的依赖包的scope。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天津储鑫盛钢材现货供应商

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表