对于最新的稳定版本,请使用 Spring Boot 3.5.5spring-doc.cadn.net.cn

打包可执行档案

该插件可以创建包含应用程序所有依赖项的可执行存档(jar 文件和 war 文件),然后可以使用java -jar.spring-doc.cadn.net.cn

打包可执行罐

可以使用bootJar任务。 当javaplugin 被应用,并且是BootJar. 这assemble任务会自动配置为依赖于bootJar任务,因此正在运行assemble(或build) 也会运行bootJar任务。spring-doc.cadn.net.cn

打包可执行文件战争

可以使用bootWar任务。 当warplugin 被应用,并且是BootWar. 这assemble任务会自动配置为依赖于bootWar任务,因此正在运行assemble(或build) 也会运行bootWar任务。spring-doc.cadn.net.cn

打包可执行和可部署的战争

可以打包 war 文件,以便可以使用java -jar并部署到外部容器。 为此,应将嵌入的 servlet 容器依赖项添加到providedRuntime配置,例如:spring-doc.cadn.net.cn

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目录,它们不会与外部容器自己的类发生冲突。spring-doc.cadn.net.cn

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

打包可执行文件和普通存档

默认情况下,当bootJarbootWar任务配置后,则jarwar任务配置为plain作为其存档分类器的约定。 这确保了bootJarjarbootWarwar具有不同的输出位置,允许同时构建可执行存档和普通存档。spring-doc.cadn.net.cn

如果您希望可执行存档(而不是普通存档)使用分类器,请配置分类器,如以下示例所示jarbootJar任务:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	archiveClassifier = 'boot'
}

tasks.named("jar") {
	archiveClassifier = ''
}
tasks.named<BootJar>("bootJar") {
	archiveClassifier.set("boot")
}

tasks.named<Jar>("jar") {
	archiveClassifier.set("")
}

或者,如果您希望根本不构建普通存档,请禁用其任务,如以下示例所示jar任务:spring-doc.cadn.net.cn

tasks.named("jar") {
	enabled = false
}
tasks.named<Jar>("jar") {
	enabled = false
}
不要禁用jar创建本机映像时的任务。 有关详细信息,请参阅 #33238

配置可执行存档打包

BootJarBootWartasks 是 Gradle 的JarWar任务。 因此,打包 jar 或 war 时可用的所有标准配置选项在打包可执行 jar 或 war 时也可用。 还提供了许多特定于可执行 jar 和 war 的配置选项。spring-doc.cadn.net.cn

配置主类

默认情况下,可执行文件的主类将通过查找具有public static void main(String[])方法。spring-doc.cadn.net.cn

也可以使用任务的mainClass财产:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	mainClass = 'com.example.ExampleApplication'
}
tasks.named<BootJar>("bootJar") {
	mainClass.set("com.example.ExampleApplication")
}

或者,可以使用mainClassSpring Boot DSL 的属性:spring-doc.cadn.net.cn

springBoot {
	mainClass = 'com.example.ExampleApplication'
}
springBoot {
	mainClass.set("com.example.ExampleApplication")
}

如果application插件已应用其mainClass属性必须配置,并且可以用于相同的目的:spring-doc.cadn.net.cn

application {
	mainClass = 'com.example.ExampleApplication'
}
application {
	mainClass.set("com.example.ExampleApplication")
}

最后,Start-Class属性可以在任务的清单上配置:spring-doc.cadn.net.cn

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 中排除。spring-doc.cadn.net.cn

如果要包含developmentOnly配置,配置其任务的类路径以包含配置,如以下示例所示bootWar任务:spring-doc.cadn.net.cn

tasks.named("bootWar") {
	classpath configurations.developmentOnly
}
tasks.named<BootWar>("bootWar") {
	classpath(configurations["developmentOnly"])
}

配置需要解包的库

大多数库在嵌套在可执行存档中时可以直接使用,但是某些库可能存在问题。 例如,JRuby 包含自己的嵌套 jar 支持,该支持假定jruby-complete.jar始终在文件系统上直接可用。spring-doc.cadn.net.cn

为了处理任何有问题的库,可以将可执行存档配置为在运行可执行存档时将特定的嵌套 jar 解压缩到临时目录。 可以使用与源 jar 文件的绝对路径匹配的 Ant 样式模式将库标识为需要解包:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	requiresUnpack '**/jruby-complete-*.jar'
}
tasks.named<BootJar>("bootJar") {
	requiresUnpack("**/jruby-complete-*.jar")
}

为了获得更多控制,也可以使用闭包。 闭包将传递一个FileTreeElement并且应该返回一个boolean指示是否需要拆包。spring-doc.cadn.net.cn

使存档完全可执行

Spring Boot 提供对完全可执行的存档的支持。 通过在前面添加一个知道如何启动应用程序的 shell 脚本,使存档完全可执行。 在类 Unix 平台上,此启动脚本允许存档像任何其他可执行文件一样直接运行或作为服务安装。spring-doc.cadn.net.cn

目前,某些工具不接受此格式,因此您可能并不总是能够使用此技术。 例如jar -xf可能无法以静默方式提取已完全可执行的 jar 或 war。 建议仅在打算直接执行此选项时启用此选项,而不是使用java -jar或将其部署到 servlet 容器。

要使用此功能,必须启用启动脚本的包含:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	launchScript()
}
tasks.named<BootJar>("bootJar") {
	launchScript()
}

这会将 Spring Boot 的默认启动脚本添加到存档中。 默认启动脚本包括多个具有合理默认值的属性。 可以使用properties财产:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	launchScript {
		properties 'logFilename': 'example-app.log'
	}
}
tasks.named<BootJar>("bootJar") {
	launchScript {
		properties(mapOf("logFilename" to "example-app.log"))
	}
}

如果默认启动脚本不能满足您的需求,则script属性可用于提供自定义启动脚本:spring-doc.cadn.net.cn

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属性:spring-doc.cadn.net.cn

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/classesBOOT-INF/lib分别。 同样地bootWar构建一个存档,其中包含应用程序的类WEB-INF/classesWEB-INF/libWEB-INF/lib-provided. 对于需要从 jar 的内容构建 docker 映像的情况下,能够进一步分离这些目录以便将它们写入不同的层非常有用。spring-doc.cadn.net.cn

分层 jar 使用与常规引导打包 jar 相同的布局,但包含一个描述每一层的附加元数据文件。spring-doc.cadn.net.cn

默认情况下,定义了以下层:spring-doc.cadn.net.cn

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

要禁用此功能,您可以通过以下方式执行此作:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	layered {
		enabled = false
	}
}
tasks.named<BootJar>("bootJar") {
	layered {
		enabled.set(false)
	}
}

创建分层 jar 或 war 时,spring-boot-jarmode-toolsjar 将作为依赖项添加到您的存档中。 在类路径上使用这个 jar,您可以在一种特殊模式下启动您的应用程序,该模式允许引导代码运行与您的应用程序完全不同的东西,例如,提取层的东西。 如果希望排除此依赖关系,可以通过以下方式进行:spring-doc.cadn.net.cn

tasks.named("bootJar") {
	includeTools = false
}
tasks.named<BootJar>("bootJar") {
	includeTools.set(false)
}

自定义层配置

根据您的应用程序,您可能需要调整图层的创建方式并添加新图层。spring-doc.cadn.net.cn

这可以使用描述如何将 jar 或 war 分成层以及这些层的顺序的配置来完成。 以下示例显示了如何显式定义上述默认排序:spring-doc.cadn.net.cn

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"))
	}
}

layeredDSL 使用三个部分进行定义:spring-doc.cadn.net.cn

嵌 套intoLayer闭包用于applicationdependencies部分以声明图层的内容。 这些闭包按定义的顺序(从上到下)进行评估。 任何未被先前认领的内容intoLayer关闭仍然可供后续人员考虑。spring-doc.cadn.net.cn

intoLayer使用嵌套的闭包声明内容includeexclude调用。 这applicationclosure 对 include/exclude 参数使用 Ant 样式的路径匹配。 这dependencies部分用途group:artifact[:version]模式。 它还提供includeProjectDependencies()excludeProjectDependencies()可用于包含或排除项目依赖项的方法。spring-doc.cadn.net.cn

如果没有include调用,然后考虑所有内容(未被早期关闭认领)。spring-doc.cadn.net.cn

如果没有exclude调用,则不应用排除项。spring-doc.cadn.net.cn

查看dependencies闭包,我们可以看到第一个intoLayer将声明application层。 下一个intoLayer将声明snapshot-dependencies层。 第三场也是最后一场intoLayer将声明剩余的任何内容(在本例中,不是项目依赖项或 SNAPSHOT 的任何依赖项)dependencies层。spring-doc.cadn.net.cn

application关闭也有类似的规则。 首次认领org/springframework/boot/loader/**内容spring-boot-loader层。 然后为application层。spring-doc.cadn.net.cn

命令intoLayer添加闭包通常与层的写入顺序不同。 因此,layerOrder方法必须始终被调用,并且必须覆盖intoLayer调用。