Spring Boot 2 with Gradle - 从单个代码库构建/编译不同版本Basic、Pro、Ultimate

问题描述

项目详情

我有一个使用 Gradle 作为构建工具的 spring boot 2 项目。我使用 Java 8 作为 Java 版本。 Thymeleaf 用于模板引擎。

我的目标

我想构建不同的版本,例如 Base 版、Pro 版和 Ultimate 版。例如,假设 Base 版本有 5 个功能。 Pro 版具有 Base 版的所有功能,另外还有 5 个功能。终极版拥有专业版的所有功能,并增加了 5 项功能

我想到的解决方案和互联网搜索解决方

  1. 为不同的版本保留不同的分支。但这里的问题是如何实际管理代码库、修补修复和引入新功能等。我也搜索过这种方法,但所有人都说不要使用它,因为这不是一个好的选择。
  2. 使用 Gradle 构建多个版本。我知道在 Android 中有一个功能可以构建多种风格的应用程序,例如用于开发、质量检查和生产。是否有任何可用于制作版本的 Spring Boot 功能
  3. 使用某种配置。我们可以有一个基于它的配置文件,我们可以根据版本打开/关闭功能。但这很容易被黑客入侵。所以我不敢用。
  4. 使用许可。这与第 3 点相同,但略有不同。
  5. 使用带有一些 Gradle 配置的 java 模块功能(显然我必须升级我的 java 版本)。在构建时,我们可以包含基于

那么我如何创建不同的版本?在这种情况下制作不同版本的最佳解决方案是什么?每个版本都与其前一版本共享一些共同特征?

请考虑我想要一个单一的代码库。因此,修复错误会很容易,因为它们共享一些通用代码/功能

解决方法

您可以使用依赖项和 Java 的 SPI...

你可以在一些核心模块中定义一个提供者接口(这里我称之为“:core”)

package com.example;

interface FlavorProvider {

    String getFlavor();

}

然后在 basic 模块中定义它的实现:

package com.example;

public class BasicFlavorProvider implements FlavorProvider {

    @Override
    public String getFlavor() {
        return "BASIC!";
    }

}

以及包含行 resources/META-INF/services/com.example.FlavorProvider

的文件 com.example.BasicFlavorProvider

另一个在 pro 模块中

package com.example;

public class ProFlavorProvider implements FlavorProvider {

    @Override
    public String getFlavor() {
        return "PRO!";
    }
}

以及包含行 resources/META-INF/services/com.example.FlavorProvider

的文件 com.example.ProFlavorProvider

然后在您的应用程序中,可选择将任一模块包含为基于项目属性的依赖项:

    implementation(project(":core"))
    if (project.hasProperty("pro")) {
        implementation(project(":pro"))
    } else {
        implementation(project(":basic"))
    }

在你的主课中你可以这样做:

package com.example;

import java.util.ServiceLoader;

public class Main {

    private final ServiceLoader<FlavorProvider> provider = ServiceLoader.load(FlavorProvider.class);

    public static void main(String[] args) {
        new Main().run();
    }

    private void run() {
        provider.forEach(p -> System.out.println(p.getFlavor()));
    }
}

那么:

➜ ./gradlew app:run

> Task :app:run
BASIC!

还有:

➜ ./gradlew app:run -Ppro

> Task :app:run
PRO!

YMMV,这并没有考虑到 Spring ?