0%

SpringBoot-Gradle插件

介绍

Spring Boot Gradle插件在Gradle中提供Spring Boot支持。它允许您打包可执行的jar或war文件,运行Spring引导应用程序,并使用spring-boot-dependencies提供的依赖项管理。Spring Boot的Gradle插件需要Gradle 6(6.3或更高)。Gradle 5.6也被支持,但是这种支持已被否决,并将在未来的版本中被删除。

除了本用户指南之外,还提供了API文档

入门

要开始使用插件,它需要应用到你的项目。

该插件被发布到Gradle的插件门户,可以使用plugins块进行应用:

1
2
3
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
}
1
2
3
plugins {
id("org.springframework.boot") version "2.3.4.RELEASE"
}

独立应用的插件对项目做了很少的改变。相反,当某些其他插件被应用时,插件会检测并做出相应的反应。例如,当应用java插件时,将自动配置用于构建可执行jar的任务。典型的Spring引导项目将应用groovyjavaorg.jetbrain .kotlin.jvm插件,还使用io.spring.dependency-management插件或Gradle本地的bom支持来进行依赖管理。例如:

1
2
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
1
2
3
4
5
6
plugins {
java
id("org.springframework.boot") version "2.3.4.RELEASE"
}

apply(plugin = "io.spring.dependency-management")

要了解更多关于Spring Boot插件在应用其他插件时的行为,请参阅对其他插件的反应部分

依赖管理

为了管理Spring引导应用程序中的依赖关系,您可以应用io.Spring.dependency-management插件,或者,如果您使用的是Gradle 6或更高版本,使用Gradle的原生bom支持。前者的主要好处是它提供了基于属性的管理版本定制,而使用后者可能会导致更快的构建。

使用依赖项管理插件管理依赖项

当您应用io.pring.dependency-management插件时,Spring Boot的插件将自动从您正在使用的Spring Boot版本中导入Spring引导依赖的bom。这提供了类似于Maven用户所享受的依赖项管理体验。例如,它允许您在声明在bom中管理的依赖项时省略版本号。要使用这个功能,可以用通常的方式声明依赖关系,但是省略版本号:

1
2
3
4
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
}
1
2
3
4
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
}

定制版本管理

当依赖项管理插件应用时,spring-boot-dependenciesbom会自动导入,它使用属性来控制它管理的依赖项的版本。浏览Spring引导参考中的依赖版本附录以获得这些属性的完整列表。

若要自定义托管版本,请设置其相应的属性。例如,定制由SLF4J控制的SLF4J的版本。版本属性:

1
ext['slf4j.version'] = '1.7.20'
1
extra["slf4j.version"] = "1.7.20"

Note

每个Spring引导版本都针对一组特定的第三方依赖项进行设计和测试。重写版本可能会导致兼容性问题,应该小心处理。

单独使用SpringBoot的依赖项管理

Spring Boot的依赖项管理可以在项目中使用,而无需将Spring Boot的插件应用到该项目。SpringBootPlugin类提供了一个BOM_COORDINATES常量,它可以用来导入bom,而不需要知道它的组ID、工件ID或版本。

首先,配置项目依赖于Spring Boot插件,但不应用它:

1
2
3
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE' apply false
}
1
2
3
plugins {
id("org.springframework.boot") version "2.3.4.RELEASE" apply false
}

Spring Boot插件对依赖项管理插件的依赖关系意味着您可以使用依赖项管理插件而不必声明它的依赖关系。这也意味着您将自动使用与Spring Boot使用的依赖管理插件相同的版本。

应用依赖管理插件,然后配置它来导入Spring Boot的bom:

1
2
3
4
5
6
7
apply plugin: 'io.spring.dependency-management'

dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
1
2
3
4
5
6
7
apply(plugin = "io.spring.dependency-management")

the<DependencyManagementExtension>().apply {
imports {
mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
}

上面的Kotlin代码有点笨拙。这是因为我们使用了强制的方式来应用依赖管理插件。

我们可以从根父项目中应用插件,或者使用plugins块,就像我们为Spring引导插件所做的那样,从而使代码不那么笨拙。这种方法的缺点是,它迫使我们指定依赖管理插件的版本:

1
2
3
4
5
6
7
8
9
10
11
plugins {
java
id("org.springframework.boot") version "2.3.4.RELEASE" apply false
id("io.spring.dependency-management") version "1.0.10.RELEASE"
}

dependencyManagement {
imports {
mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
}

拓展

要了解更多关于依赖管理插件的功能,请参阅它的文档

用Gradle的BOM支持依赖管理

Gradle允许使用bom来管理一个项目的版本,通过声明它作为一个平台或enforcedPlateform依赖。平台依赖关系将bom中的版本视为建议,而依赖关系图中的其他版本和约束可能会导致使用bom中声明的依赖关系的版本。一个enforcedPlatform依赖关系将bom中的版本视为需求,它们将覆盖依赖关系图中发现的任何其他版本。

SpringBootPlugin类提供了一个BOM_COORDINATES常量,它可以用来声明SpringBoot bom的依赖关系,而不需要知道它的组ID、工件ID或版本,如下面的例子所示:

1
2
3
dependencies {
implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
1
2
3
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
}

一个平台或强制平台将只限制声明它的配置的版本,或者从声明它的配置扩展的版本。因此,可能需要在多个配置中声明相同的依赖项。

定制版本管理

当使用Gradle的bom支持时,您不能使用spring-boot-dependencies的属性来控制它所管理的依赖项的版本。相反,您必须使用Gradle提供的一种机制。其中一种机制是解决策略。SLF4J的模块都在org.slf4j组中,通过配置组中的每个依赖项来使用特定的版本来控制它们的版本,如下面的示例所示:

1
2
3
4
5
6
7
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'org.slf4j') {
details.useVersion '1.7.20'
}
}
}
1
2
3
4
5
6
7
configurations.all {
resolutionStrategy.eachDependency {
if (requested.group == "org.slf4j") {
useVersion("1.7.20")
}
}
}

Warning

每个Spring引导版本都针对一组特定的第三方依赖项进行设计和测试。重写版本可能会导致兼容性问题,应该小心处理。

打包可执行的档案

插件可以创建包含应用程序所有依赖项的可执行档案(jar文件和war文件),然后可以使用java -jar运行。

打包可执行的Jars

可执行jar可以使用bootJar任务构建。该任务在应用java插件时自动创建,它是BootJar的一个实例。assemble任务被自动配置为依赖于bootJar任务,因此运行组装(或构建)也将运行bootJar任务。

打包可执行的Wars

可执行war可以使用bootWar任务构建。该任务是在war插件应用时自动创建的,它是BootWar的一个实例。组装任务被自动配置为依赖于启动任务,因此运行组装(或构建)也将运行启动任务。

打包可执行可部署的Wars

war文件可以打包,以便使用java -jar执行并部署到外部容器中。为此,嵌入式servlet容器依赖关系应该添加到providedRuntime配置中,例如:

1
2
3
4
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
}
1
2
3
4
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}

这确保了它们被打包在war文件的WEB-INF/lib-provided的目录中,在那里它们不会与外部容器自己的类发生冲突。

Note

providedRuntime优先于Gradle的compileOnly配置,因为除了其他限制外,compileOnly依赖项不在测试类路径上,因此任何基于web的集成测试都将失败。

打包可执行的正常档案

默认情况下,当配置了bootJarbootWar任务时,将禁用jarwar任务。通过启用jarwar任务,可以将项目配置为同时构建可执行存档和普通存档:

1
2
3
jar {
enabled = true
}
1
2
3
tasks.getByName<Jar>("jar") {
enabled = true
}

为了避免可执行存档和普通存档被写入相同的位置,应该将其中一个配置为使用不同的位置。一种方法是配置一个分类器:

1
2
3
bootJar {
classifier = 'boot'
}
1
2
3
tasks.getByName<BootJar>("bootJar") {
classifier = "boot"
}

配置可执行归档打包

BootJarBootWar任务分别是Gradle的JarWar任务的子类。因此,在打包jar或war时可用的所有标准配置选项在打包可执行jar或war时也可用。还提供了一些特定于可执行jar和war的配置选项。

配置Main类

默认情况下,通过在任务类路径的目录中查找具有public static void main(String[])方法的类,可执行文件的主类将被自动配置。

主类也可以使用任务的mainClassName属性显式配置:

1
2
3
bootJar {
mainClassName = 'com.example.ExampleApplication'
}
1
2
3
tasks.getByName<BootJar>("bootJar") {
mainClassName = "com.example.ExampleApplication"
}

或者,主类名可以在项目范围内配置,使用Spring Boot DSL的mainClassName属性:

1
2
3
springBoot {
mainClassName = 'com.example.ExampleApplication'
}
1
2
3
springBoot {
mainClassName = "com.example.ExampleApplication"
}

如果应用程序插件已经应用,它的mainClassName项目属性必须配置,可以用于相同的目的:

1
mainClassName = 'com.example.ExampleApplication'
1
2
3
application {
mainClassName = "com.example.ExampleApplication"
}

最后,可以在任务清单上配置Start-Class属性:

1
2
3
4
5
bootJar {
manifest {
attributes 'Start-Class': 'com.example.ExampleApplication'
}
}
1
2
3
4
5
tasks.getByName<BootJar>("bootJar") {
manifest {
attributes("Start-Class" to "com.example.ExampleApplication")
}
}

包括仅限开发的依赖

默认情况下,在developmentOnly配置中声明的所有依赖项都将从可执行的jar或war中排除。

如果你想在你的档案中包含在developmentOnly配置中声明的依赖项,配置它的任务的类路径以包含配置,如下面的bootWar任务示例所示:

1
2
3
bootWar {
classpath configurations.developmentOnly
}
1
2
3
tasks.getByName<BootWar>("bootWar") {
classpath(configurations["developmentOnly"])
}

配置需要解压缩的库

当嵌套在可执行存档中时,大多数库都可以直接使用,但是某些库可能会有问题。例如,JRuby包含它自己的嵌套jar支持,它假设Jruby-complete.jar总是可以直接在文件系统上使用。

为了处理任何有问题的库,可以配置一个可执行存档,以在可执行存档运行时将特定的嵌套jar解压到一个临时目录。库可以被认为需要使用ant样式的模式来解包,这种模式与源jar文件的绝对路径相匹配:

1
2
3
bootJar {
requiresUnpack '**/jruby-complete-*.jar'
}
1
2
3
tasks.getByName<BootJar>("bootJar") {
requiresUnpack("**/jruby-complete-*.jar")
}

为了更好地控制,也可以使用闭包。闭包被传递一个FileTreeElement,并且应该返回一个布尔值,指示是否需要解包。

构建完全可执行的档案

Spring Boot提供了对完全可执行文件的支持。通过预先设置一个知道如何启动应用程序的shell脚本,可以使存档完全可执行。在类unix平台上,这个启动脚本允许像任何其他可执行文件一样直接运行存档,或者作为服务安装存档。

Note

目前,一些工具不接受这种格式,因此您可能不总是能够使用这种技术。例如,jar -xf可能悄无声息地无法提取完全可执行的jar或war。建议您仅在打算直接执行该选项时启用它,而不是使用java -jar运行它,将其部署到servlet容器或将其包含在OCI映像中。

要使用此功能,必须启用启动脚本:

1
2
3
bootJar {
launchScript()
}
1
2
3
tasks.getByName<BootJar>("bootJar") {
launchScript()
}

这将把Spring Boot的默认启动脚本添加到归档文件中。默认启动脚本包括几个具有合理默认值的属性。值可以自定义使用属性属性:

1
2
3
4
5
bootJar {
launchScript {
properties 'logFilename': 'example-app.log'
}
}
1
2
3
4
5
tasks.getByName<BootJar>("bootJar") {
launchScript {
properties(mapOf("logFilename" to "example-app.log"))
}
}

如果默认的启动脚本不满足您的需要,脚本属性可以用于提供自定义启动脚本:

1
2
3
4
5
bootJar {
launchScript {
script = file('src/custom.script')
}
}
1
2
3
4
5
tasks.getByName<BootJar>("bootJar") {
launchScript {
script = file("src/custom.script")
}
}

使用PropertiesLauncher

要使用PropertiesLauncher来启动一个可执行jar或war,配置任务的manifest来设置Main-Class属性:

1
2
3
4
5
bootWar {
manifest {
attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
}
}
1
2
3
4
5
    tasks.getByName<BootWar>("bootWar") {
manifest {
attributes("Main-Class" to "org.springframework.boot.loader.PropertiesLauncher")
}
}

打包多层的Jars

默认情况下,bootJar任务构建一个存档,其中分别在BOOT-INF/classesBOOT-INF/lib中包含应用程序的类和依赖项。对于需要从jar的内容构建docker映像的情况,进一步分离这些目录将非常有用,这样就可以将它们写入不同的层中。

分层jar使用与常规引导打包jar相同的布局,但是包含一个额外的元数据文件来描述每一层。要使用此功能,必须启用分层功能:

1
2
3
bootJar {
layered()
}
1
2
3
tasks.getByName<BootJar>("bootJar") {
layered()
}

默认情况下,定义了以下层:

  • dependencies对应任何不包含SNAPSHOT版本的依赖。
  • spring-boot-loader对应jar加载器类。
  • snapshot-dependencies对应任何包含SNAPSHOT版本的依赖。
  • application对应应用类和资源。

层顺序很重要,因为它决定了当应用程序的一部分发生更改时缓存前一层的可能性有多大。默认顺序是dependencies,spring-boot-loader,snapshot-dependencies,application。首先应该添加最不容易更改的内容,然后添加更容易更改的层。

当您创建分层jar时,spring-boot-jarmode-layertools jar将作为依赖项添加到您的jar中。有了类路径上的这个jar,您就可以以一种特殊的模式启动应用程序,这种模式允许引导代码运行与应用程序完全不同的东西,例如,提取层的东西。如果你想排除这种依赖,你可以这样做,在以下方式:

1
2
3
4
5
bootJar {
layered {
includeLayerTools = false
}
}
1
2
3
4
5
tasks.getByName<BootJar>("bootJar") {
layered {
isIncludeLayerTools = false
}
}

配置定制层

根据您的应用程序,您可能需要调整层的创建和添加新层的方式。

可以使用描述如何将jar划分为层的配置以及这些层的顺序来实现这一点。下面的示例展示了如何显式定义上面描述的默认顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bootJar {
layered {
application {
intoLayer("spring-boot-loader") {
include "org/springframework/boot/loader/**"
}
intoLayer("application")
}
dependencies {
intoLayer("snapshot-dependencies") {
include "*:*:*SNAPSHOT"
}
intoLayer("dependencies")
}
layerOrder = ["dependencies", "spring-boot-loader", "snapshot-dependencies", "application"]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tasks.getByName<BootJar>("bootJar") {
layered {
application {
intoLayer("spring-boot-loader") {
include("org/springframework/boot/loader/**")
}
intoLayer("application")
}
dependencies {
intoLayer("snapshot-dependencies") {
include("*:*:*SNAPSHOT")
}
intoLayer("dependencies")
}
layerOrder = listOf("dependencies", "spring-boot-loader", "snapshot-dependencies", "application")
}
}

分层的DSL由三部分定义:

  • application闭包定义了应用程序类和资源应该如何分层。
  • dependencies闭包定义了应该如何分层依赖关系。
  • layerOrder方法定义了层应该被写入的顺序。

嵌套的intoLayer闭包用于在applicationdependencies部分中声明某个层的内容。这些闭包按照定义它们的顺序进行评估,从上到下。任何先前没有声明过的内容都可以供以后的人考虑。

intoLayer闭包使用嵌套的包括和排除调用声明内容。应用程序闭包使用ant风格的补丁匹配包含/排除参数。依赖项部分使用group:artifact[:version]模式。

如果没有进行include调用,那么将考虑所有内容(不是由之前的闭包声明的)。

如果没有进行排除调用,则不会应用任何排除。

看看上面示例中的dependencies闭包,我们可以看到第一个intoLayer将声明snapshot-dependencies层的所有快照依赖关系。随后的intoLayer将索取依赖层剩下的任何东西(在本例中,是不是快照的任何依赖)。

应用程序闭包也有类似的规则。首先声明spring引导加载器层的org/springframework/boot/loader/**内容。然后为应用层声明所有剩余的类和资源。

Note

intoLayer闭包的添加顺序通常与层的书写顺序不同。由于这个原因,必须始终调用layerOrder方法,并且必须覆盖intoLayer调用引用的所有层。

打包OCI镜像

该插件可以使用云本地构建包从可执行jar创建一个OCI映像。可以使用bootBuildImage任务构建图像。

Note

出于安全原因,映像以非根用户的身份生成和运行,请参阅本节了解更多细节

该任务是在应用java插件时自动创建的,它是BootBuildImage的一个实例。

Note

bootBuildImage任务不能与包含启动脚本的完全可执行的Spring引导归档一起使用。在构建用于bootBuildImage的jar文件时,禁用bootJar任务中的启动脚本配置。

Docker守护进程

bootBuildImage任务需要访问Docker守护进程。默认情况下,它将通过本地连接与Docker守护进程通信。这工作Docker引擎在所有支持的平台上没有配置。

可以设置环境变量来配置bootBuildImage任务,使其使用minikube提供的Docker守护进程。下表显示了环境变量及其值:

环境变量 描述
DOCKER_HOST 包含Docker守护进程的主机和端口的URL,例如tcp://192.168.99.100:2376
DOCKER_TLS_VERIFY 当设置为1时启用安全HTTPS协议(可选)
DOCKER_CERT_PATH HTTPS证书和密钥文件的路径(DOCKER_TLS_VERIFY=1需要,否则忽略)

在Linux和macOS上,可以在minikube启动后使用eval $(minikube dockator -env)命令设置这些环境变量。

镜像定制

插件调用一个构建器来编排映像的生成。构建器包括多个构建包,它们可以检查应用程序以影响生成的映像。默认情况下,插件选择一个构建器图像。生成的图像的名称由项目属性导出。

任务属性可用于配置构建器应该如何对项目进行操作。下表总结了可用的属性及其默认值:

Property Command-line option Description Default value
builder --builder 要使用的生成器映像的名称。 gcr.io/paketo-buildpacks/builder:base-platform-api-0.3
runImage --runImage 要使用的运行映像的名称。 No default value, indicating the run image specified in Builder metadata should be used.
imageName --imageName Image name for the generated image. docker.io/library/${project.name}:${project.version}
environment Environment variables that should be passed to the builder.
cleanCache Whether to clean the cache before building. false
verboseLogging Enables verbose logging of builder operations. false

Note

该插件使用JavaPlugin的targetCompatibility属性检测项目的目标Java兼容性。默认情况下,插件指示构建包安装相同的Java版本。您可以通过设置BP_JVM_VERSION环境变量来覆盖此行为,请参阅构建器配置

Examples

定制镜像构建器并运行镜像

如果您需要自定义用于创建映像的构建器或用于启动已构建映像的运行映像,请按照以下示例配置任务:

1
2
3
4
bootBuildImage {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}
1
2
3
4
tasks.getByName<BootBuildImage>("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}

这个配置将使用一个名为mine/java-cnb-builder的构建器映像和最新的标记,以及名为mine/java-cnb-run的运行映像和最新的标记。

构建器和运行映像也可以在命令行上指定,如下例所示:

1
$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run

构建器配置

如果构建器公开配置选项,则可以使用environment属性设置这些选项。

下面的示例假设默认构建器识别BP_JVM_VERSION属性。这个属性通常用于自定义图像应该使用的JDK版本,通过指定主要版本和版本其余部分的通配符:

1
2
3
bootBuildImage {
environment = ["BP_JVM_VERSION" : "8.*"]
}
1
2
3
tasks.getByName<BootBuildImage>("bootBuildImage") {
environment = mapOf("BP_JVM_VERSION" to "8.*")
}

如果在运行构建器的Docker守护进程和构建包从其中下载构件的网络位置之间存在网络代理,则需要配置构建器以使用代理。当使用默认构建器时,可以通过设置HTTPS_PROXY和/或HTTP_PROXY环境变量来完成,如下面的例子所示:

1
2
3
4
5
6
bootBuildImage {
environment = [
"HTTP_PROXY" : "http://proxy.example.com",
"HTTPS_PROXY": "https://proxy.example.com"
]
}
1
2
3
4
tasks.getByName<BootBuildImage>("bootBuildImage") {
environment = mapOf("HTTP_PROXY" to "http://proxy.example.com",
"HTTPS_PROXY" to "https://proxy.example.com")
}

定制镜像名称

默认情况下,图像名称是从项目的名称和版本推断出来的,类似于docker.io/library/${project.name}:${project.version}。您可以通过设置任务属性来控制名称,如下面的示例所示:

1
2
3
bootBuildImage {
imageName = "example.com/library/${project.name}"
}
1
2
3
tasks.getByName<BootBuildImage>("bootBuildImage") {
imageName = "example.com/library/${project.name}"
}

注意,此配置没有提供显式标记,因此使用的是latest。也可以指定一个标签,使用${project.version},构建版本或硬编码版本中可用的任何属性。

也可以在命令行中指定图像名称,如下例所示:

1
$ gradle bootBuildImage --imageName=example.com/library/my-app:v1

发布应用程序

使用Maven插件发布

应用maven插件后,将自动创建名为bootBootArchives的bootArchives配置的Upload任务。 默认情况下,bootArchives配置包含bootJar或bootWar任务生成的归档文件。 可以将uploadBootArchives任务配置为将存档发布到Maven存储库:

1
2
3
4
5
6
7
uploadBootArchives {
repositories {
mavenDeployer {
repository url: 'https://repo.example.com'
}
}
}
1
2
3
4
5
6
7
tasks.getByName<Upload>("uploadBootArchives") {
repositories.withGroovyBuilder {
"mavenDeployer" {
"repository"("url" to "https://repo.example.com")
}
}
}

使用Maven发布插件进行发布

要发布您的Spring Boot jar或war,请使用MavenPublication上的构件方法将其添加到发布中。 将产生要发布的工件的任务传递给工件方法。 例如,要发布默认bootJar任务产生的工件:

1
2
3
4
5
6
7
8
9
10
11
12
publishing {
publications {
bootJava(MavenPublication) {
artifact bootJar
}
}
repositories {
maven {
url 'https://repo.example.com'
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
publishing {
publications {
create<MavenPublication>("bootJava") {
artifact(tasks.getByName("bootJar"))
}
}
repositories {
maven {
url = uri("https://repo.example.com")
}
}
}

使用应用程序插件分发

应用程序插件被应用时,将创建一个名为boot的发行版。 此发行版包含bootJarbootWar任务生成的归档文件,以及用于在类似Unix的平台和Windows上启动它的脚本。 可以分别通过bootDistZip和bootDistTar任务来构建Zip和tar发行版。 要使用应用程序插件,必须使用应用程序主类的名称配置其mainClassName属性。

使用Gradle运行应用程序

要在不首先建立档案的情况下运行应用程序,请使用bootRun任务:

1
$ ./gradlew bootRun

bootRun任务是BootRun的一个实例,该实例是JavaExec的子类。 这样,您就可以使用在Gradle中执行Java进程的所有常规配置选项。 该任务会自动配置为使用主源集的运行时类路径。

默认情况下,将通过在任务的类路径上的目录中查找带有public static void main(String [])方法的类来自动配置主类。

也可以使用任务的main属性明确配置主类:

1
2
3
bootRun {
main = 'com.example.ExampleApplication'
}
1
2
3
tasks.getByName<BootRun>("bootRun") {
main = "com.example.ExampleApplication"
}

另外,可以使用Spring Boot DSL的mainClassName属性在项目范围内配置主类名称:

1
2
3
springBoot {
mainClassName = 'com.example.ExampleApplication'
}
1
2
3
springBoot {
mainClassName = "com.example.ExampleApplication"
}

默认情况下,bootRun将配置JVM以优化其启动,以在开发过程中加快启动速度。 可以通过使用optimizedLaunch属性来禁用此行为,如以下示例所示:

1
2
3
bootRun {
optimizedLaunch = false
}
1
2
3
tasks.getByName<BootRun>("bootRun") {
isOptimizedLaunch = false
}

如果已应用了应用程序插件,则必须配置其mainClassName属性,并且可以将其用于相同的目的:

1
2
3
application {
mainClassName = 'com.example.ExampleApplication'
}

1
2
3
application {
mainClassName = "com.example.ExampleApplication"
}

将参数传递给您的应用程序

与所有JavaExec任务一样,在使用Gradle 4.9或更高版本时,可以使用--args ='<arguments>'从命令行将参数传递到bootRun中。 例如,要使用名为dev active的概要文件运行您的应用程序,可以使用以下命令:

1
$ ./gradlew bootRun --args='--spring.profiles.active=dev'

请参考javadoc的JavaExec.setArgsString获取更多。

传递系统属性到应用

由于bootRun是标准的JavaExec任务,因此可以通过在构建脚本中指定系统属性来将其传递给应用程序的JVM。 可以对这些值进行参数化,并使用-P标志将其作为属性传递给命令行。

有关更多详细信息,请参见JavaExec.systemProperty的javadoc

重新加载资源

如果将devtools添加到您的项目中,它将自动监视您的应用程序的更改。 另外,您可以配置bootRun,以便从其源位置加载应用程序的静态资源:

1
2
3
bootRun {
sourceResources sourceSets.main
}
1
2
3
tasks.getByName<BootRun>("bootRun") {
sourceResources(sourceSets["main"])
}

这使得它们可以在实时应用程序中重新加载,这在开发时可能会有所帮助。

集成Actuator

生成构建信息

如果存在META-INF/build-info.properties文件,Spring Boot Actuator的信息端点将自动发布有关构建的信息。 提供了一个BuildInfo任务来生成此文件。 使用任务的最简单方法是通过插件的DSL:

1
2
3
springBoot {
buildInfo()
}
1
2
3
springBoot {
buildInfo()
}

这将配置一个名为bootBuildInfo的BuildInfo任务,并使Java插件的classes任务依赖于该任务。 任务的目标目录将在主要源集资源(通常是build/resources/main)的输出目录中为META-INF

默认情况下,生成的构建信息来自项目:

Property Default value
build.artifact “ bootJar”或“ bootWar”任务的基本名称,如果不存在这样的任务,则为“ unspecified”
build.group The group of the project
build.name The name of the project
build.version The version of the project
build.time 项目建立的时间

可以使用DSL自定义属性:

1
2
3
4
5
6
7
8
9
10
springBoot {
buildInfo {
properties {
artifact = 'example-app'
version = '1.2.3'
group = 'com.example'
name = 'Example application'
}
}
}
1
2
3
4
5
6
7
8
9
10
springBoot {
buildInfo {
properties {
artifact = "example-app"
version = "1.2.3"
group = "com.example"
name = "Example application"
}
}
}

build.time的默认值为构建项目的瞬间。 这样做的副作用是任务永远不会是最新的。 结果,构建将花费更长的时间,因为必须执行更多的任务,包括项目的测试。 另一个副作用是任务的输出将始终更改,因此构建将不会真正可重复。 如果您对构建性能或可重复性的重视程度高于build.time属性的准确性,则将time设置为null或固定值。

还可以将其他属性添加到构建信息中:

1
2
3
4
5
6
7
8
9
10
springBoot {
buildInfo {
properties {
additional = [
'a': 'alpha',
'b': 'bravo'
]
}
}
}
1
2
3
4
5
6
7
8
9
10
springBoot {
buildInfo {
properties {
additional = mapOf(
"a" to "alpha",
"b" to "bravo"
)
}
}
}

响应其它插件

当应用另一个插件时,Spring Boot插件会通过对项目的配置进行各种更改来做出反应。 本节描述了这些更改。

响应Java插件

当Gradle的java插件应用于项目时,Spring Boot插件:

  1. 创建一个名为bootJar的BootJar任务,该任务将为该项目创建一个可执行的胖jar。该jar将包含主源集的运行时类路径上的所有内容;类包装在BOOT-INF/classes中,而jars包装在BOOT-INF/lib
  2. 将组装任务配置为依赖于bootJar任务。
  3. 禁用jar任务。
  4. 创建一个名为bootBuildImageBootBuildImage任务,该任务将使用buildpack创建一个OCI映像。
  5. 创建一个名为bootRunBootRun任务,该任务可用于运行您的应用程序。
  6. 创建一个名为bootArchives的配置,其中包含bootJar任务生成的工件。
  7. 为仅在开发时需要的依赖项(例如Spring Boot的Devtools)创建一个名为developmentOnly的配置,不应将其打包在可执行的jar和wars中。
  8. 将任何未配置编码的JavaCompile任务配置为使用UTF-8
  9. 将任何JavaCompile任务配置为使用-parameters编译器参数。

响应Kotlin插件

当Gradle的war插件应用于项目时,Spring Boot插件将:

  1. 创建一个名为bootWarBootWar任务,该任务将为该项目创建可执行的,激烈的战争。 除了标准打包之外,提供的运行时配置中的所有内容都将打包在WEB-INF/lib提供的文件中。
  2. 将组装任务配置为依赖于bootWar任务。
  3. 禁用war任务。
  4. bootArchives配置配置为包含bootWar任务生成的工件。

响应依赖管理插件

当Gradle的应用程序插件应用于项目时,Spring Boot插件将:

  1. 创建一个名为bootStartScriptsCreateStartScripts任务,该任务将创建脚本,这些脚本使用java -jarbootArchives配置中启动工件。该任务配置为使用applicationDefaultJvmArgs属性作为其defaultJvmOpts属性的约定。
  2. 创建一个名为boot的新发行版,并将其配置为在libArchives目录的bootArchives配置中包含工件,在bin目录中将其包含启动脚本。
  3. bootRun任务配置为使用mainClassName属性作为其main属性的约定。
  4. 配置bootRun任务以使用applicationDefaultJvmArgs属性作为其jvmArgs属性的约定。
  5. 配置bootJar任务以将mainClassName属性用作其清单中Start-Class条目的约定。
  6. bootWar任务配置为使用mainClassName属性作为清单中Start-Class条目的约定。

响应Maven插件

将Gradle的maven插件应用于项目后,Spring Boot插件将配置uploadBootArchives Upload任务,以确保在其生成的pom中没有声明依赖项。