maven依赖关系及其在java项目中的实际工作方式

6qqygrtg  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(443)

我在google上寻找了这些答案,但没有找到我问题的确切答案,通常只是对maven和pom以及生命周期阶段的概述。我的确切问题是:
可传递依赖项。假设我有一个主java项目,叫做“project-a”,它有另一个项目作为它的依赖项,比如一个数据库java项目,它有所有的crud方法,叫做“dependency-x”,它有 spring-boot-starter-jpa-1.X.X 其pom中列出的版本。现在我也宣布 spring-boot-starter-jpa-2.X.X (注意版本)直接在javaproject-a的pom中。如果我正确理解了可传递的依赖关系,spring-boot-starter-jpa-1.x.x(来自dependency-xdb项目)将通过dependency-x(db)项目可传递地(间接地)导入。那么哪种依赖关系获胜呢?哪个是进口的?因为它们是两个不同的版本,这显然是个问题。是否必须显式添加 <exclusion> 标记pom中的所有依赖项,这些依赖项会拉入其他与项目当前依赖项冲突的可传递依赖项???


多个依赖项。当您在pom.xml中声明依赖项时,当您将相同的依赖项包含到不同版本的两倍时会发生什么;哪个被选中/导入到您的项目中,maven是如何决定的?我假设,如果maven找不到这种依赖性,在你的第一次回购中,你的 <repositories> 列出(假设你有超过一个回购上市)你的pom,它会去名单1比1,直到它发现它是正确的?即

<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>

家长pom到底是如何工作的?我知道我可以包括 <parent></parent> 标签里面有一个依赖项,我可以点击ctrl+b(windows)或command+b(mac),它将带我到源pom(父级),我可以查看所有的内容。这是如何工作的-它从哪里得到这个文件?
所有的“父”pom,比如“springbootstarterjpa”依赖关系,实际上只是指向maven中央repo上的pom文件,它进一步指向maven解析并导入到您的项目中的单个jar吗???

<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>
li9yvcax

li9yvcax1#

就解决可传递依赖关系而言,最短路径获胜。这里也记录了这一点。

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.

那么哪种依赖关系获胜呢?哪个是进口的?
启动程序jpa2.x获胜,因为它有最短的路径。
对于同一依赖项的多个版本,我建议运行

mvn dependency:tree

看哪一个被包括进来或者是否有错误。
家长pom到底是如何工作的?
父pom只是对当前项目“继承”自的项目的引用。关于如何从父级解析依赖关系,有一些特定的规则。在我看来,最重要的一点是父级允许您在一个地方为共同的兄弟项目添加依赖项,所有这些项目都可以从中继承它们的依赖项。springboot遵循这个模式来引入starterpom版本解析。当然,拥有一个父pom是可选的,你可以拥有一个没有父pom的项目。

67up9zun

67up9zun2#

通常,如果依赖关系树中有同一jar的不同版本,“最近的”依赖关系获胜。
您可以通过在中显式设置可传递依赖项的版本来覆盖此行为 <dependencyManagement> . 不要使用排除来管理版本。
父级像依赖项一样被解析,即来自mavencentral这样的存储库。
父级的内容和pom的内容是“合并”的,这导致了“有效pom”,您可以在命令行或ide中查看它。

qpgpyjmq

qpgpyjmq3#

家长pom到底是如何工作的?我
您似乎想了解项目继承在maven中是如何工作的。这是一个庞大的课题。这解决了构建pom(项目继承)的主要方法以及与之相关的结果。
关于你的前两个问题:
那么哪种依赖关系获胜呢?哪个是进口的?
当包含相同的依赖项两次不同的版本时会发生什么;哪个被选中/导入到您的项目中,maven是如何决定的?
虽然你的问题是有道理的,但maven并没有就此提供任何具体的保证。冲突版本的结果只是一个实现细节。
我更愿意告诉您,为了保证根据依赖版本的需求进行一致的打包,您必须对此执行显式检查。
您可以实现它,也可以将maven插件(如maven enforcer插件)与现有规则(如:
dependencyconvergence-确保所有依赖项聚合到同一版本。
BandUpplicatePomDependencyVersions-强制项目不具有重复的已声明依赖项。
requireupperbounddeps-确保每个(可传递的)依赖项都解析为其指定的版本或更高版本。
规则列表非常密集,如果没有人符合您的需要,您甚至可以编写自己的规则。
关于如何使用dependencyconvergence规则声明插件执行的示例:

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>3.0.0-M3</version>
        <executions>
          <execution>
            <id>enforce</id>
            <configuration>
              <rules>
                <dependencyConvergence/>
              </rules>
            </configuration>
            <goals>
              <goal>enforce</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

相关问题