java - Maven 依赖项以及它们在 Java 项目中的实际工作方式
问题描述
我在谷歌上寻找这些答案,但找不到我的问题的确切答案,通常只是对 Maven 和 pom 和生命周期阶段的概述。我的确切问题是:
- 传递依赖。假设我有一个名为“Project-A”的主要 Java 项目,并且它有另一个项目作为其依赖项,例如一个具有所有 CRUD 方法的数据库 Java 项目,称为“Dependency-X”,其
spring-boot-starter-jpa-1.X.X
版本列在其聚甲醛。现在说我也spring-boot-starter-jpa-2.X.X
直接在 Java Project-A 的 POM 中声明(注意版本)。如果我正确理解传递依赖项,spring-boot-starter-jpa-1.XX(来自 Dependency-X db 项目)将通过 Dependency-X (db) 项目传递(间接)导入。那么哪个依赖会获胜?哪个被进口?由于它们是两个不同的版本,这显然是一个问题。您是否必须明确添加<exclusion>
标记到您的 POM 中的所有依赖项,这些依赖项拉入与您的项目当前依赖项冲突的其他传递依赖项???
- 多重依赖。当您在 pom.xml 中声明依赖项时,当您包含相同的依赖项两次不同版本时会发生什么;哪个被选中/导入到您的项目中,Maven 是如何决定的?而且我假设,如果 maven 在您的列表中列出的第一个 repo 中找不到这个依赖项-a
<repositories>
(假设您列出了超过 1 个 repo)您的 pom,它将逐个列表下去,直到它认为正确吗?IE
<dependency>
<groupId>org.mydependency</groupId>
<artifactId>dependency-a</artifactId>
<version>6.6.6</version>
</dependency>
<dependency>
<groupId>org.mydependency</groupId>
<artifactId>dependency-a</artifactId>
<version>8.8.8</version>
</dependency>
- parent-pom 到底是如何工作的?我知道我可以在其中包含
<parent></parent>
带有依赖项的标签,我可以单击 ctrl + B (windows) 或 command + B (mac),它将带我到 source pom (parent) 并且我可以查看所有内容。这是如何工作的——它从哪里得到这个文件?
是否所有“父”pom,例如“spring-boot-starter-jpa”依赖项实际上只是指向 maven 中央 repo 上的 POM 文件,进一步指向单个 JARS,maven 解析并导入到您的项目中???
IE
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
解决方案
就解决传递依赖而言,最短路径获胜。这也记录在这里。
Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.
"nearest definition" means that the version used will be the closest one to your project in the tree of dependencies. Consider this tree of dependencies:
A
├── B
│ └── C
│ └── D 2.0
└── E
└── D 1.0
In text, dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter.
那么哪个依赖获胜?哪个被进口?
boot starter jpa 2.x 获胜,因为它的路径最短。
对于同一依赖项的多个版本,我建议运行
mvn dependency:tree
查看包含哪一个或是否有错误。
parent-pom 到底是如何工作的?
父 pom 只是对当前项目“继承”的项目的引用。关于如何从父母那里解决依赖关系有一定的规则。在我看来,最重要的事情是,父级允许您在所有兄弟项目都可以从中继承其依赖项的地方为常见的兄弟项目添加依赖项。Spring boot 遵循这个模式来引入 starter pom 版本解析。当然,拥有父 pom 是可选的,您可以拥有一个没有父 pom 的项目。
推荐阅读
- arrays - ReactRedux 数组属性为空
- python - 在Python中将一对变量分配给两个变量的最小值/最大值
- python - message.content 到 json 文件 python discord bot
- c++ - 无法使用列表列表找出重载的构造函数
- javascript - 如何在 AngularJS 中使用 Highcharts
- laravel-5 - 获取一个类别中的所有类别和项目 - laravel 5
- javascript - 选择 h1 内的文本 - javascript
- android - Kotlin FileWriter 不创建任何文件
- ruby-on-rails - 我如何指定我想使用哪个版本的 ruby?
- html - 访问 VBA 代码以从 AA 里程计算器网站提取谷歌地图结果