Maven 再学习之 bom 与 super pom

问题由来

作为java开发的我们,一定会经常遇到下面这两个看似非常类似的异常信息:
java.lang.NoSuchMethodError
java.lang.ClassNotFoundException

maven 预备知识

maven 依赖解析规则:
Rule 1: Nearest First;
Rule 2: If distance is the same, the one who declare first wins;

实际上就是pom文件,定义<dependencyManagement>
dependency management takes precedence over dependency mediation for transitive dependencies

super pom

parent pom

玩过spring boot的人,一定都知道,SB提供一个spring-boot-starter-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

然后就可以在<dependencies>里面引入自己想要使用的starter,并且在使用时无需指定starter的具体版本,默认使用什么parent引入的版本号。当然,maven支持定义version标签来更改特定的starter的版本号。

在Parent POM中,会定义子项目必须遵守的一些约定,如Java版本,编码,公共第三方依赖的版本,测试规范,maven版本检查,打包规范,发布仓库声明等。
通过该规范,可以保证子项目在打包、发布、版本依赖、环境配置等方面的一致性,减少冲突和不规范,降低开发环境配置复杂度。

BOM

BOM(Bill of Materials)定义一整套相互兼容的jar包版本集合,使用时只需要依赖该BOM文件,即可放心的使用需要的依赖jar包,且无需再指定版本号。BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。

为什么需要BOM?
使用BOM除了可以方便使用者在声明依赖的客户端时不需要指定版本号外,最主要的原因是可以解决依赖冲突。
考虑以下的依赖场景:
Project A依赖B 2.1.3和C 1.2.0版本;
B 2.1.3依赖D 1.1.6版本;
C 1.2.0依赖D 1.3.0版本。
在上例中,Project A对于D的依赖就出现冲突,按照maven dependency mediation的规则,最后生效的是1.1.6版本(就近原则)。
在这种情况下,由于C依赖1.3.0版本的D,但是在运行时生效的确是1.1.6版本,所以在运行时很容易产生问题,如 NoSuchMethodError, ClassNotFoundException等。

如何定义BOM?
BOM本质上是一个普通的POM文件,区别是对于使用方而言,生效的只有<dependencyManagement>这一个部分。只需要在<dependencyManagement>定义对外发布的客户端版本即可。

如何使用BOM?
业务应用使用时,首先需要在pom.xml文件的<dependencyManagement>中,声明对BOM的依赖,然后在实际使用依赖的地方把版本去掉即可。

猜你喜欢

转载自blog.csdn.net/lonelymanontheway/article/details/80623408