1. Overview
1.概述
In this quick tutorial, we’re going to look at how Maven, a tool based on the concept of Project Object Model (POM), can make use of a BOM or “Bill Of Materials”.
在这个快速教程中,我们将看看Maven这个基于项目对象模型(POM)概念的工具如何利用BOM或 “材料清单”。
For more details about Maven, you can check our article Apache Maven Tutorial.
关于Maven的更多细节,您可以查看我们的文章Apache Maven教程。
2. Dependency Management Concepts
2.依赖性管理的概念
To understand what a BOM is and what we can use it for, we first need to learn basic concepts.
要了解什么是BOM以及我们可以用它来做什么,我们首先需要学习基本概念。
2.1. What Is Maven POM?
2.1.什么是Maven POM?
Maven POM is an XML file that contains information and configurations (about the project) that are used by Maven to import dependencies and to build the project.
Maven POM是一个包含信息和配置(关于项目)的XML文件,Maven用它来导入依赖关系并构建项目。
2.2. What Is Maven BOM?
2.2.什么是Maven BOM?
BOM stands for Bill Of Materials. A BOM is a special kind of POM that is used to control the versions of a project’s dependencies and provide a central place to define and update those versions.
BOM是Bill Of Materials的缩写。BOM是一种特殊的POM,用于控制项目的依赖版本,并为定义和更新这些版本提供一个中心位置。
BOM provides the flexibility to add a dependency to our module without worrying about the version that we should depend on.
BOM提供了为我们的模块添加依赖的灵活性,而不必担心我们应该依赖的版本。
2.3. Transitive Dependencies
2.3.过渡性依存关系
Maven can discover the libraries that are needed by our own dependencies in our pom.xml and includes them automatically. There’s no limit to the number of dependency levels that the libraries are gathered from.
Maven可以在pom.xml中发现我们自己的依赖项所需的库,并自动包含它们。对收集到的库的依赖级别没有限制。
The conflict here comes when 2 dependencies refer to different versions of a specific artifact. Which one will be included by Maven?
当2个依赖关系指的是一个特定工件的不同版本时,就会产生冲突。哪一个会被Maven包含?
The answer here is the “nearest definition”. This means that the version used will be the closest one to our project in the tree of dependencies. This is called dependency mediation.
这里的答案是 “最近的定义”。这意味着所使用的版本将是在依赖关系树中与我们的项目最接近的一个。这就是所谓的依赖性调解。。
Let’s see the following example to clarify the dependency mediation:
让我们看看下面的例子,以澄清依赖关系的调解。
A -> B -> C -> D 1.4 and A -> E -> D 1.0
This example shows that project A depends on B and E. B and E have their own dependencies which encounter different versions of the D artifact. Artifact D 1.0 will be used in the build of A project because the path through E is shorter.
这个例子显示项目A依赖于B和E. B和E有自己的依赖关系,遇到不同版本的D工件。在构建A项目时,将使用工件D1.0,因为通过E的路径更短。
There are different techniques to determine which version of the artifacts should be included:
有不同的技术来确定哪个版本的工件应该被包括在内。
- We can always guarantee a version by declaring it explicitly in our project’s POM. For instance, to guarantee that D 1.4 is used, we should add it explicitly as a dependency in the pom.xml file.
- We can use the Dependency Management section to control artifact versions as we will explain later in this article.
2.4. Dependency Management
2.4.依赖性管理
Simply put, Dependency Management is a mechanism to centralize the dependency information.
简单地说,依赖性管理是一种集中依赖性信息的机制。
When we have a set of projects that inherit a common parent, we can put all dependency information in a shared POM file called BOM.
当我们有一组项目继承了一个共同的父项目时,我们可以把所有的依赖信息放在一个叫做BOM的共享POM文件中。
Following is an example of how to write a BOM file:
下面是一个如何编写BOM文件的例子。
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>baeldung</groupId>
<artifactId>Baeldung-BOM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>BaelDung-BOM</name>
<description>parent pom</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>b</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
As we can see, the BOM is a normal POM file with a dependencyManagement section where we can include all an artifact’s information and versions.
正如我们所看到的,BOM是一个普通的POM文件,有一个dependencyManagement部分,在这里我们可以包括所有工件的信息和版本。
2.5. Using the BOM File
2.5.使用BOM文件
There are 2 ways to use the previous BOM file in our project and then we will be ready to declare our dependencies without having to worry about version numbers.
有2种方法可以在我们的项目中使用以前的BOM文件,然后我们就可以申报我们的依赖关系而不必担心版本号。
We can inherit from the parent:
我们可以从父辈那里继承。
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>baeldung</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Test</name>
<parent>
<groupId>baeldung</groupId>
<artifactId>Baeldung-BOM</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
</project>
As we can see our project Test inherits the Baeldung-BOM.
我们可以看到,我们的项目Test继承了Baeldung-BOM。
We can also import the BOM.
我们也可以导入BOM.。
In larger projects, the approach of inheritance is not efficient because the project can inherit only a single parent. Importing is the alternative as we can import as many BOMs as we need.
在较大的项目中,继承的方法并不有效,因为项目只能继承一个父项目。导入是另一种选择,因为我们可以根据需要导入尽可能多的BOM。
Let’s see how we can import a BOM file into our project POM:
让我们看看如何将BOM文件导入我们的项目POM中。
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>baeldung</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Test</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>baeldung</groupId>
<artifactId>Baeldung-BOM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2.6. Overwriting BOM Dependency
2.6.覆盖BOM依存关系
The order of precedence of the artifact’s version is:
人造物的版本的优先顺序是。
- The version of the artifact’s direct declaration in our project pom
- The version of the artifact in the parent project
- The version in the imported pom, taking into consideration the order of importing files
- dependency mediation
- We can overwrite the artifact’s version by explicitly defining the artifact in our project’s pom with the desired version
- If the same artifact is defined with different versions in 2 imported BOMs, then the version in the BOM file that was declared first will win
3. Spring BOM
3.Spring物料清单
We may find that a third-party library, or another Spring project, pulls in a transitive dependency to an older release. If we forget to explicitly declare a direct dependency, unexpected issues can arise.
我们可能会发现,一个第三方库或另一个Spring项目拉入了一个与旧版本的横向依赖关系。如果我们忘记明确地声明一个直接的依赖关系,就会出现意想不到的问题。
To overcome such problems, Maven supports the concept of BOM dependency.
为了克服这些问题,Maven支持BOM依赖的概念。
We can import the spring-framework-bom in our dependencyManagement section to ensure that all Spring dependencies are at the same version:
我们可以在dependencyManagement部分导入spring-framework-bom,以确保所有Spring的依赖关系处于同一版本。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
We don’t need to specify the version attribute when we use the Spring artifacts as in the following example:
当我们使用Spring工件时,我们不需要指定version属性,如下面的例子。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
4. Conclusion
4.总结
In this quick article, we showed the Maven Bill-Of-Material Concept and how to centralize the artifact’s information and versions in a common POM.
在这篇文章中,我们展示了Maven Bill-Of-Material的概念,以及如何将工件的信息和版本集中到一个共同的POM中。
Simply put, we can then either inherit or import it to make use of the BOM benefits.
简单地说,我们就可以继承或导入它来利用BOM的好处。
The code examples in the article can be found over on GitHub.
文章中的代码示例可以在GitHub上找到over。