Maven 工程 jar 包冲突的解决

一、基本概念

(1)依赖传递
Maven 工程 jar 包冲突的解决
可以发现添加 springmvc 的核心依赖坐标之后,会发现出现除了 spring-webmvc 以外的其他 jar。 因为我们的项目依赖 spring-webmv.jar,而spring-webmv.jar 会依赖 spring-beans.jar 等等, 所以 spring-beans.jar 这些 jar 包也出现在了我们的 maven 工程中, 这种现象我们称为依赖传递。
从下图中可看到他们的关系: (请注意spring-beans 的版本)
Maven 工程 jar 包冲突的解决

  • 直接依赖:项目中直接导入的jar包,就是该项目的直接依赖包。
  • 传递依赖:项目中没有直接导入的jar包,可以通过项目直接依赖jar包传递到项目中去。

(2)jar 包冲突
此时再添加一个spring-context 依赖:
Maven 工程 jar 包冲突的解决
此时可以发现这两个jar 包都依赖了 spring-beans:
Maven 工程 jar 包冲突的解决
可以发现这里 spring-context依赖 spirng-beans-4.2.4, spring-webmvc依赖 spring-beans-5.0.2,但是发现 spring-beans-5.0.2 加入到工程中,而我们希望 spirng-beans-4.2.4 加入工程,这就造成了依赖冲突

二、解决 jar 包冲突方式:第一声明者优先原则

第一声明者优先原则: 在 pom 文件定义依赖,先声明的依赖为准

此时如果将上边 spring-webmvc 和 spring-context 顺序颠倒,系统将导入 spirng-beans-4.2.4
Maven 工程 jar 包冲突的解决
Maven 工程 jar 包冲突的解决

三、解决 jar 包冲突方式:路径近者优先原则

例如: 还是上述情况, spring-contex 和 spring-webmvc 都会传递过来 spirng-beans, 那如果直接把 spring-beans 的依赖直接写到 pom 文件中,那么项目就不会再使用其他依赖传递来的 spring-beans,因为自己直接在 pom 中定义 spring-beans 要比其他依赖传递过来的路径要近。
Maven 工程 jar 包冲突的解决
Maven 工程 jar 包冲突的解决

四、解决 jar 包冲突方式:排除依赖(推荐使用)

上边的问题也可以通过排除依赖方法辅助依赖调解,如下:
比如在依赖 spring-webmvc 的设置中添加排除依赖,排除 spring-beans,
下边的配置表示:依赖 spring-webmvc,但排除 spring-webmvc 所依赖的 spring-beans。
Maven 工程 jar 包冲突的解决
当我们要排除某个jar包下依赖包,在配置exclusions标签的时候,内部可以不写版本号。
因为此时依赖包使用的版本和默认和本jar包一样
Maven 工程 jar 包冲突的解决

五、锁定版本

面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用

Maven 工程 jar 包冲突的解决
还可以把版本号提取出来,使用<properties>标签设置成变量
Maven 工程 jar 包冲突的解决
注意:在工程中锁定依赖的版本并不代表在工程中添加了依赖,如果工程需要添加锁定版本的依赖则需要单独添加<dependencies></dependencies>标签,如下:
Maven 工程 jar 包冲突的解决
上边添加的依赖并没有指定版本,原因是已在<dependencyManagement>中锁定了版本,所以在<dependency>下不需要再指定版本。