对于最新的稳定版本,请使用 Spring Boot 3.5.5! |
打包可执行档案
该插件可以创建包含应用程序所有依赖项的可执行存档(jar 文件和 war 文件),然后可以使用java -jar
.
打包可执行罐
可以使用bootJar
任务。
当java
plugin 被应用,并且是BootJar
.
这assemble
任务会自动配置为依赖于bootJar
任务,因此正在运行assemble
(或build
) 也会运行bootJar
任务。
打包可执行文件战争
可以使用bootWar
任务。
当war
plugin 被应用,并且是BootWar
.
这assemble
任务会自动配置为依赖于bootWar
任务,因此正在运行assemble
(或build
) 也会运行bootWar
任务。
打包可执行和可部署的战争
可以打包 war 文件,以便可以使用java -jar
并部署到外部容器。
为此,应将嵌入的 servlet 容器依赖项添加到providedRuntime
配置,例如:
-
Groovy
-
Kotlin
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}
这确保了它们被打包在战争文件的WEB-INF/lib-provided
目录,它们不会与外部容器自己的类发生冲突。
providedRuntime 比 Gradle 的compileOnly 配置为,除其他限制外,compileOnly 依赖项不在测试类路径上,因此任何基于 Web 的集成测试都将失败。 |
打包可执行文件和普通存档
默认情况下,当bootJar
或bootWar
任务配置后,则jar
或war
任务配置为plain
作为其存档分类器的约定。
这确保了bootJar
和jar
或bootWar
和war
具有不同的输出位置,允许同时构建可执行存档和普通存档。
如果您希望可执行存档(而不是普通存档)使用分类器,请配置分类器,如以下示例所示jar
和bootJar
任务:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
archiveClassifier = 'boot'
}
tasks.named("jar") {
archiveClassifier = ''
}
tasks.named<BootJar>("bootJar") {
archiveClassifier.set("boot")
}
tasks.named<Jar>("jar") {
archiveClassifier.set("")
}
或者,如果您希望根本不构建普通存档,请禁用其任务,如以下示例所示jar
任务:
-
Groovy
-
Kotlin
tasks.named("jar") {
enabled = false
}
tasks.named<Jar>("jar") {
enabled = false
}
不要禁用jar 创建本机映像时的任务。
有关详细信息,请参阅 #33238。 |
配置可执行存档打包
这BootJar
和BootWar
tasks 是 Gradle 的Jar
和War
任务。
因此,打包 jar 或 war 时可用的所有标准配置选项在打包可执行 jar 或 war 时也可用。
还提供了许多特定于可执行 jar 和 war 的配置选项。
配置主类
默认情况下,可执行文件的主类将通过查找具有public static void main(String[])
方法。
也可以使用任务的mainClass
财产:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
mainClass = 'com.example.ExampleApplication'
}
tasks.named<BootJar>("bootJar") {
mainClass.set("com.example.ExampleApplication")
}
或者,可以使用mainClass
Spring Boot DSL 的属性:
-
Groovy
-
Kotlin
springBoot {
mainClass = 'com.example.ExampleApplication'
}
springBoot {
mainClass.set("com.example.ExampleApplication")
}
如果application
插件已应用其mainClass
属性必须配置,并且可以用于相同的目的:
-
Groovy
-
Kotlin
application {
mainClass = 'com.example.ExampleApplication'
}
application {
mainClass.set("com.example.ExampleApplication")
}
最后,Start-Class
属性可以在任务的清单上配置:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
manifest {
attributes 'Start-Class': 'com.example.ExampleApplication'
}
}
tasks.named<BootJar>("bootJar") {
manifest {
attributes("Start-Class" to "com.example.ExampleApplication")
}
}
如果主类是用 Kotlin 编写的,则应使用生成的 Java 类的名称。
默认情况下,这是 Kotlin 类的名称,带有Kt 后缀已添加。
例如ExampleApplication 成为ExampleApplicationKt .
如果使用@JvmName 那么应该使用该名称。 |
包括仅开发依赖项
默认情况下,在developmentOnly
配置将从可执行的 jar 或 war 中排除。
如果要包含developmentOnly
配置,配置其任务的类路径以包含配置,如以下示例所示bootWar
任务:
-
Groovy
-
Kotlin
tasks.named("bootWar") {
classpath configurations.developmentOnly
}
tasks.named<BootWar>("bootWar") {
classpath(configurations["developmentOnly"])
}
配置需要解包的库
大多数库在嵌套在可执行存档中时可以直接使用,但是某些库可能存在问题。
例如,JRuby 包含自己的嵌套 jar 支持,该支持假定jruby-complete.jar
始终在文件系统上直接可用。
为了处理任何有问题的库,可以将可执行存档配置为在运行可执行存档时将特定的嵌套 jar 解压缩到临时目录。 可以使用与源 jar 文件的绝对路径匹配的 Ant 样式模式将库标识为需要解包:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
requiresUnpack '**/jruby-complete-*.jar'
}
tasks.named<BootJar>("bootJar") {
requiresUnpack("**/jruby-complete-*.jar")
}
为了获得更多控制,也可以使用闭包。
闭包将传递一个FileTreeElement
并且应该返回一个boolean
指示是否需要拆包。
使存档完全可执行
Spring Boot 提供对完全可执行的存档的支持。 通过在前面添加一个知道如何启动应用程序的 shell 脚本,使存档完全可执行。 在类 Unix 平台上,此启动脚本允许存档像任何其他可执行文件一样直接运行或作为服务安装。
目前,某些工具不接受此格式,因此您可能并不总是能够使用此技术。
例如jar -xf 可能无法以静默方式提取已完全可执行的 jar 或 war。
建议仅在打算直接执行此选项时启用此选项,而不是使用java -jar 或将其部署到 servlet 容器。 |
要使用此功能,必须启用启动脚本的包含:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
launchScript()
}
tasks.named<BootJar>("bootJar") {
launchScript()
}
这会将 Spring Boot 的默认启动脚本添加到存档中。
默认启动脚本包括多个具有合理默认值的属性。
可以使用properties
财产:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
launchScript {
properties 'logFilename': 'example-app.log'
}
}
tasks.named<BootJar>("bootJar") {
launchScript {
properties(mapOf("logFilename" to "example-app.log"))
}
}
如果默认启动脚本不能满足您的需求,则script
属性可用于提供自定义启动脚本:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
launchScript {
script = file('src/custom.script')
}
}
tasks.named<BootJar>("bootJar") {
launchScript {
script = file("src/custom.script")
}
}
使用属性Starters
要使用PropertiesLauncher
要启动可执行的 jar 或 war,请配置任务的清单以将Main-Class
属性:
-
Groovy
-
Kotlin
tasks.named("bootWar") {
manifest {
attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher'
}
}
tasks.named<BootWar>("bootWar") {
manifest {
attributes("Main-Class" to "org.springframework.boot.loader.launch.PropertiesLauncher")
}
}
包装分层罐或战争
默认情况下,bootJar
任务构建一个存档,其中包含应用程序的类和依赖项BOOT-INF/classes
和BOOT-INF/lib
分别。
同样地bootWar
构建一个存档,其中包含应用程序的类WEB-INF/classes
和WEB-INF/lib
和WEB-INF/lib-provided
.
对于需要从 jar 的内容构建 docker 映像的情况下,能够进一步分离这些目录以便将它们写入不同的层非常有用。
分层 jar 使用与常规引导打包 jar 相同的布局,但包含一个描述每一层的附加元数据文件。
默认情况下,定义了以下层:
-
dependencies
对于版本不包含的任何非项目依赖项SNAPSHOT
. -
spring-boot-loader
对于 jar 加载器类。 -
snapshot-dependencies
对于其版本包含SNAPSHOT
. -
application
用于项目依赖项、应用程序类和资源。
层顺序很重要,因为它决定了当应用程序的一部分发生更改时缓存先前层的可能性。
默认顺序为dependencies
,spring-boot-loader
,snapshot-dependencies
,application
.
应首先添加最不可能更改的内容,然后添加更有可能更改的图层。
要禁用此功能,您可以通过以下方式执行此作:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
layered {
enabled = false
}
}
tasks.named<BootJar>("bootJar") {
layered {
enabled.set(false)
}
}
创建分层 jar 或 war 时,spring-boot-jarmode-tools
jar 将作为依赖项添加到您的存档中。
在类路径上使用这个 jar,您可以在一种特殊模式下启动您的应用程序,该模式允许引导代码运行与您的应用程序完全不同的东西,例如,提取层的东西。
如果希望排除此依赖关系,可以通过以下方式进行:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
includeTools = false
}
tasks.named<BootJar>("bootJar") {
includeTools.set(false)
}
自定义层配置
根据您的应用程序,您可能需要调整图层的创建方式并添加新图层。
这可以使用描述如何将 jar 或 war 分成层以及这些层的顺序的配置来完成。 以下示例显示了如何显式定义上述默认排序:
-
Groovy
-
Kotlin
tasks.named("bootJar") {
layered {
application {
intoLayer("spring-boot-loader") {
include "org/springframework/boot/loader/**"
}
intoLayer("application")
}
dependencies {
intoLayer("application") {
includeProjectDependencies()
}
intoLayer("snapshot-dependencies") {
include "*:*:*SNAPSHOT"
}
intoLayer("dependencies")
}
layerOrder = ["dependencies", "spring-boot-loader", "snapshot-dependencies", "application"]
}
}
tasks.named<BootJar>("bootJar") {
layered {
application {
intoLayer("spring-boot-loader") {
include("org/springframework/boot/loader/**")
}
intoLayer("application")
}
dependencies {
intoLayer("application") {
includeProjectDependencies()
}
intoLayer("snapshot-dependencies") {
include("*:*:*SNAPSHOT")
}
intoLayer("dependencies")
}
layerOrder.set(listOf("dependencies", "spring-boot-loader", "snapshot-dependencies", "application"))
}
}
这layered
DSL 使用三个部分进行定义:
-
这
application
闭包定义了应用程序类和资源应如何分层。 -
这
dependencies
闭包定义了依赖关系应该如何分层。 -
这
layerOrder
方法定义了图层的写入顺序。
嵌 套intoLayer
闭包用于application
和dependencies
部分以声明图层的内容。
这些闭包按定义的顺序(从上到下)进行评估。
任何未被先前认领的内容intoLayer
关闭仍然可供后续人员考虑。
这intoLayer
使用嵌套的闭包声明内容include
和exclude
调用。
这application
closure 对 include/exclude 参数使用 Ant 样式的路径匹配。
这dependencies
部分用途group:artifact[:version]
模式。
它还提供includeProjectDependencies()
和excludeProjectDependencies()
可用于包含或排除项目依赖项的方法。
如果没有include
调用,然后考虑所有内容(未被早期关闭认领)。
如果没有exclude
调用,则不应用排除项。
查看dependencies
闭包,我们可以看到第一个intoLayer
将声明application
层。
下一个intoLayer
将声明snapshot-dependencies
层。
第三场也是最后一场intoLayer
将声明剩余的任何内容(在本例中,不是项目依赖项或 SNAPSHOT 的任何依赖项)dependencies
层。
这application
关闭也有类似的规则。
首次认领org/springframework/boot/loader/**
内容spring-boot-loader
层。
然后为application
层。
命令intoLayer 添加闭包通常与层的写入顺序不同。
因此,layerOrder 方法必须始终被调用,并且必须覆盖intoLayer 调用。 |