【问题标题】:Maintaining two different Spring boot versions in single Maven package在单个 Maven 包中维护两个不同的 Spring Boot 版本
【发布时间】:2016-09-25 17:50:57
【问题描述】:

假设我们有一个共享库包。相同的pom如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.project.microservice-a</groupId>
<artifactId>shared-lib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>shared-lib</name>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <start-class>com.projects.lib1.Application</start-class>
    <java.version>1.8</java.version>
</properties>
....
....
</project>

有项目使用上述共享库,有以下pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.projects.microservice</groupId>
<artifactId>accounts</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>accounts</name>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
    <dependencies>
    <dependency>
        <groupId>com.project.microservice-a</groupId>
        <artifactId>shared-lib</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
....
<dependencies>

然后有一个特殊的子系统在 Spring-boot-starter-parent.1.3.5 作为父级运行,它不会与 Spring-boot-starter-parent-1.2.3 一起使用 shared-lib。

使用Spring-boot.1.3.5导入shared-lib,需要修改pom.xml的parent为Spring 1.3.5版本,然后构建。这会在构建所有子系统时导致维护问题,因为 Jenkins CI 使用主分支从 Github 构建所有 JAR。我们可以手动指定一个单独的分支,但是为两个分支维护相同的代码是简单的重复。

任何人都可以提出一个解决方案,IMO 可能是实现其中之一的方法:

  1. 创建一个嵌入 Spring 1.2.3 和 Spring 1.3.5 的包,并在其他子系统中指定所需的依赖版本。

  2. 使用 Spring Boot 1.3.5 构建原始客户端包,并在所需子系统中使用依赖项时强制它使用旧版本的 Spring Boot。

【问题讨论】:

  • 我不明白您的问题...您是否希望在同一个项目中使用两个不同版本的 Spring Boot,具体取决于...?它是一个多模块 maven 项目吗?
  • @jcgarcia :改进了问题。顺便说一句,有一个共享项目与其他两个项目用作依赖项,但两个项目都有不同的 Spring Boot 版本。所以我希望在两个版本中都构建 shared-lib,而不需要维护重复的代码。

标签: java spring maven spring-mvc spring-boot


【解决方案1】:

假设这些是您对每个项目的依赖项:

  1. 共享库:
    • spring-boot-foo:1.2.3
  2. 项目-a:
    • 共享库
    • spring-boot-bar:1.2.3
  3. 项目-b:
    • 共享库
    • spring-boot-baz:1.3.5

现在您希望 project-a 使用所有 spring-boot 库中的 1.2.3,而 project-b 使用 1.3.5,而不管 spring-boot 库 shared-lib 指定什么?

将以下内容放入您的 pom.xml:

<properties>
    <spring-boot.version>1.3.5.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

如果你的项目有一个共同的父 pom.xml,你可以把它放在那里,然后简单地将 spring-boot.version 值更改为你认为合适的每个项目的其他值。否则你将不得不复制它。

或者,如果这个所谓的 BOM (&lt;scope&gt;import&lt;/scope&gt;) 不起作用,您可以明确列出每个依赖项,例如:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-foo</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-bar</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-baz</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

阅读有关管理 spring-boot 依赖项的更多信息:http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html

更新:

您可以根据需要以相同的方式管理其他依赖项。例如:

<properties>
    <spring-data-releasetrain.version>Gosling-SR4</spring-data-releasetrain.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>${spring-data-releasetrain.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

【讨论】:

  • 请注意,这将允许您为每个模块选择要使用的依赖项,但您不能同时使用两者。即使 Maven 可以将两者都放在类路径中,Java 也只会选择一个。如果您需要在运行时同时使用两者,则必须使用某种可以执行此操作的高级 ClassLoader。在这种情况下,您可以查看 OSGI,例如。
  • 更新了我的问题,使其更具描述性。您还会推荐相同的解决方案吗?此外,我应该将您的第一个建议添加到所有项目还是只添加到使用 shared-lib 的项目?
  • 是的,它确实适合您的用例。但是,您应该在共享库中使用旧版本 (1.2.3) 的依赖项,而不是新版本 (1.3.5)。这是因为与 1.2.3 一起工作的东西不太可能在 1.3.5 中被破坏,但很有可能在 1.3.5 中工作的东西在 1.2.3 中可能还不可用。因此,与 1.2.3 共享构建并让其他人根据需要将其依赖管理到 1.3.5。我建议将此添加到所有项目的依赖项管理部分,因为它会使您的意图清晰,并且以后只需更改一个属性即可轻松升级。
  • 获取given error 在新的 spring 微服务中使用 shared-lib 以及您建议的依赖管理代码。 POMhere
  • 由于某种原因,似乎有更多的不一致之处。你能检查一下你的 .war 档案中添加了哪些库吗?然后您可以简单地验证所有库的版本是否正确。对于 Spring-Data 库,它们都应该来自同一个发布序列,例如 Spring Boot 1.3.x 的 Gosling
猜你喜欢
  • 1970-01-01
  • 2018-04-30
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 2011-11-26
  • 2021-12-19
  • 1970-01-01
相关资源
最近更新 更多