为啥有时会跳过 maven 依赖项中的版本号?
Posted
技术标签:
【中文标题】为啥有时会跳过 maven 依赖项中的版本号?【英文标题】:Why version number in maven dependency is skipped at times?为什么有时会跳过 maven 依赖项中的版本号? 【发布时间】:2014-12-14 00:04:21 【问题描述】:我对 maven 的功能还很陌生.. 我已经看到在放置依赖项的 pom.xml 中,有时只提到了 groupID 和 artifact id 并且跳过了版本。为什么是这样? 例如下面的依赖来自springsource网站http://spring.io/guides/gs/authenticating-ldap/
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-jndi</artifactId>
<version>1.5.5</version>
</dependency>
</dependencies>
但在 *** 的其他地方也提到版本不是可选的。如果有人能解释这一点,我会很高兴。
【问题讨论】:
【参考方案1】:是的,版本不是可选的。
考虑一个多模块应用程序,它有 10 个模块,比如 module1、module2.. module10。假设所有这 10 个项目都使用spring-boot-starter-web
。如果这 10 个模块相互依赖,您可能希望在这 10 个模块中使用相同版本的 spring-boot-starter-web
。
现在想象一下,如果您要在所有这 10 个 pom 文件中保持相同的版本号,然后在您想使用更新版本的 spring-boot-starter-web
时更新所有这些文件,那将是多么复杂。如果可以集中管理这些信息不是更好吗?
Maven 有一个已知的 <dependencyManagement/>
标签来解决这个问题并集中依赖信息。
对于您提供的示例,下面的一组链接将帮助您了解如何解析版本号,即使它不存在于您正在查看的 pom 中。
查看你正在查看的 pom 的父标签 (https://github.com/spring-guides/gs-authenticating-ldap/blob/master/complete/pom.xml)
现在让我们去那个父节点看看版本是否在那个 pom 的 dependencyManagement 部分中指定(https://github.com/spring-projects/spring-boot/blob/master/spring-boot-starters/spring-boot-starter-parent/pom.xml)。不,它也没有在那里定义。现在让我们看看父母的父母。 https://github.com/spring-projects/spring-boot/blob/master/spring-boot-dependencies/pom.xml。哦,是的,我们那里有版本号。
类似于dependencyManagement,插件可以在pom的pluginManagement部分进行管理。
希望能解释一下。
参考:dependencyManagement,pluginManagement
【讨论】:
【参考方案2】:对coderplus
的优秀答案的一些补充:
在多模块项目中,将项目使用的工件配置在根pom.xml
的dependencyManagement
中被认为是一种很好的做法,这样您就不必在子模块中编写版本pom.xml
s (就像您的示例中的某些依赖项一样)。
声明作为属性使用的外部库的版本,然后在dependencyManagement/dependencies/dependency/version
中使用这些属性也被认为是一种很好的做法。这或多或少已经完成here:
<properties>
<logback.version>1.1.2</logback.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>$logback.version</version>
</dependency>
</dependencies>
</dependencyManagement>
在多模块项目中,您还应该在dependencyManagement
中声明自己的工件。
但请不要明确写出版本(就像 Spring 人做的here),改用$project.version
。
所以写起来会更好:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>$project.version</version>
</dependency>
而不是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
</dependency>
here.
整个目的是DRY,不要重复自己。您在 POM 中的冗余声明越多,它们的打击就越大。寻找过时的依赖项非常有趣。
【讨论】:
以上是关于为啥有时会跳过 maven 依赖项中的版本号?的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使我的 maven 依赖项中有第三方依赖项,也只需要 OSGi 容器中的第三方依赖项?
Prisma 易受攻击的依赖项未在 Maven 依赖项中显示:树