繁体   English   中英

你如何参数化 Spring Boot Gradle 插件?

[英]How do you parameterize the Spring Boot Gradle plugin?

我们正在寻求从 Maven 迁移到 Gradle,并且已经解决了您期望替换父 POM 概念的大部分挑战。 有一个关键点我们还没有弄清楚。 我们需要指定我们在全局范围内使用的 Spring Boot 版本,但是我遇到了我尝试过的两种解决方案的无效构建文件问题:

  • 我尝试将plugins { id 'org.springframework.boot' version '2.1.17.RELEASE' }声明放在通用构建脚本中。 构建错误“只有项目和设置构建脚本可以包含插件 {} 块。”
  • 我尝试调用通用构建文件来指定springBootVersion参数并在插件声明中使用它。 构建错误“在 plugins {} 块之前只允许 buildscript {} 和其他插件 {} 脚本块,不允许其他语句”

如果我可以简单地apply plugin: 'org.springframework.boot'所有这一切都会更容易,但 Gradle 找不到该插件。 除了一个微服务外,所有微服务都在单一版本的 Spring Boot 上,如果可能的话,我们希望能够进行全局升级。

附加信息

  • 我有大约 40 个微服务以及这些服务使用的一些库
  • 他们每个人都有单独的存储库,所以正常的父/子方法不起作用
  • Maven 父 POM 允许您将该 POM 作为它自己的资源发布,并且 Gradle 中没有 1:1 等效功能
  • Gradle pluginManagement概念对我们也不起作用,因为它解决了 Spring Boot 插件但现在找不到依赖项管理插件。

我的常用构建脚本包含在此处:

repositories {
    mavenLocal()
    
    /* Removed our internal repositories */

    jcenter()
    mavenCentral()
}

apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'

group = 'nedl-unified-platform'

/* Required to publish Spring Boot microservices to publish to repository */
configurations {
    [apiElements, runtimeElements].each {
        it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
        it.outgoing.artifact(bootJar)
    }
}

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
    withJavadocJar()
    withSourcesJar()
}

ext {
    set('springBootVersion', '2.1.17.RELEASE')
    set('springCloudVersion', "Greenwich.SR6")
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

jacoco {
    toolVersion = "0.8.5"
    reportsDir = file("$buildDir/reports/jacoco")
}

test {
    finalizedBy jacocoTestReport // report is always generated after tests run
}

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.2
            }
        }
    }
}

jacocoTestReport {
    dependsOn test // tests are required to run before generating the report
    
    reports {
        xml.enabled true
        html.destination file("${reportsDir}/jacocoHtml")
        xml.destination file("${reportsDir}/jacocoReport.xml")
    }
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }

    repositories {
        /* excluded for privacy and brevity's sake, our internal Maven repo */
    }
}

这是由我们要参数化的项目构建脚本调用的:

plugins {
    id 'org.springframework.boot' version springBootVersion
}

apply from: "https://mycentral.repo/project-common/develop/build.gradle"

dependencies {
    implementation  'org.springframework.boot:spring-boot-starter-actuator'
    implementation  'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    implementation  'ch.qos.logback:logback-classic'
    implementation  'javax.annotation:javax.annotation-api:1.3.2'
    implementation  'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
    implementation  'org.glassfish.jaxb:jaxb-runtime:2.4.0-b180830.0438'
    testImplementation  'org.springframework.boot:spring-boot-starter-test'
}

version = '0.0.2-SNAPSHOT'

我不确定我是否完全理解您的问题,但您应该使用 Gradle 方式共享配置:根项目配置。

不要在每个项目中都包含通用构建脚本,而是创建一个全局项目并在此处设置配置。

root
|
| --- projectA
| --- projectB
| --- projectC

使用相应的settings.gradle

include 'projectA'
include 'projectB'
include 'projectC'

在根build.gradle ,设置版本

ext.springBootVersion = '2.1.17.RELEASE'

在使用 springBoot 的子项目中,假设projectB ,在子build.gradle应用插件

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }

    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
    }
}

apply plugin: 'org.springframework.boot'

我认为这里的差距是在 maven 中你有父pom的概念,而在 Gradle 中你没有。 没有像您所说的 1:1 映射,但是您可以在 Gradle 中使用插件,并应用插件。

您将拥有的最接近的事情是,如果您开发了自己的 Gradle 插件,您的每个项目都可以应用该插件。 然后,您的自定义插件将在所有项目中通用的其他任何内容中配置 Spring Boot。 该插件将定义您希望所有其他项目使用的 Spring Boot 版本。

如果只关心配置 Spring Boot,您不会从自定义插件中获得太多好处,它还需要做其他事情。 如果您没有丰富的经验,可能很难创建 Gradle 插件。 你失去了build.gradle所有熟悉的语法,你实际上必须编写代码,(有一些相似之处,但我发现这很困难),如果可能的话,我会避免它。

我建议您首先将 spring boot 插件直接应用于您的一个微服务项目,使其工作,然后再做另一个。 在您完成了其中的一些之后,您将能够看到它们之间的共同点,以及是否确实值得投资开发一个全局插件。 不过你真的需要小心,因为你的全局插件有可能既是福也是祸。 它可能会减少维护人员的大量手动工作,但如果你弄错了,这会让他们感到悲伤,然后他们会想回到 maven。

我不确定我是否理解您全局定义的 Spring 版本要求。 除非您使用 SNAPSHOT 依赖项/插件(不好的不要这样做),(或您的存储库之外的黑魔法 settings.gralde),您将不得不在某处放置一些版本。 作为替代方案,您可以创建自己的自定义任务,该任务在check生命周期中运行,该任务将检查 spring(或您的插件)的版本并在它不是最新版本时打印警告,并鼓励开发人员升级。

额外的信息参数化的插件与性能可以做到把你的财产gradle.properties作为springBootVersion=2.1.17.RELEASE

这个例子对我有用,虽然我可能不理解所有的限制。

如果我们将 Spring Boot 的版本抽象为固定 URI(例如在内部 CI/CD 服务器上),那么在每个项目/repo 的build.gradle考虑这build.gradle

buildscript {
    repositories {
        jcenter()
    }

    def SPRING_BOOT_VERSION_URI = 'http://localhost:5151/api-server/spring-boot.txt'
    ext.springBootVersion = new URL(SPRING_BOOT_VERSION_URI).getText().trim()

    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
    }
}

apply plugin: 'org.springframework.boot'

apply from: "../common/build.gradle"

我意识到最初的问题指出apply plugin不起作用,但我不清楚这是否排除了这种方法。

最后,请注意,很容易将其从简单的文本文件扩展为更正式的 JSON 规范(根据团队的需要量身定制)。

如果将此添加到根项目中,则所有子项目都应该能够从同一组 Spring Boot 依赖项中导入。 神奇的成分是allprojects块:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

ext {
  springBootVersion = '2.3.4.RELEASE'
}

allprojects {
    apply plugin: 'java'
    apply plugin: 'io.spring.dependency-management'

    dependencyManagement {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
        }
    }
}
apply plugin: 'org.springframework.boot'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM