此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.0spring-doc.cn

打包可执行存档文件

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

打包可执行 Jar

可以使用该任务构建可执行 jar。 该任务是在应用插件时自动创建的,并且是 BootJar 的一个实例。 任务会自动配置为取决于任务,因此运行 (或 ) 也将运行该任务。bootJarjavaassemblebootJarassemblebuildbootJarspring-doc.cn

打包可执行 Wars

可以使用 task 构建 Executable wars。 该任务是在应用插件时自动创建的,并且是 BootWar 的一个实例。 任务会自动配置为取决于任务,因此运行 (或 ) 也将运行该任务。bootWarwarassemblebootWarassemblebuildbootWarspring-doc.cn

打包可执行和可部署的 War

可以打包 war 文件,以便可以使用外部容器执行并部署到外部容器。 为此,应将嵌入式 servlet 容器依赖项添加到配置中,例如:java -jarprovidedRuntimespring-doc.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")
}

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

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

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

默认情况下,在配置 or 任务时,将 or 任务配置为用作其档案分类器的约定。 这可确保 and 或 and 具有不同的输出位置,从而允许同时构建可执行存档和普通存档。bootJarbootWarjarwarplainbootJarjarbootWarwarspring-doc.cn

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

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

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

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

或者,如果您不希望完全构建 plain 存档,请禁用其任务,如以下示例所示:jarspring-doc.cn

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

配置可执行归档文件打包

BootJarBootWar 任务分别是 Gradle 和 tasks 的子类。 因此,打包 jar 或 war 时可用的所有标准配置选项在打包可执行 jar 或 war 时也可用。 还提供了许多特定于可执行 jar 和 war 的配置选项。JarWarspring-doc.cn

配置 Main 类

默认情况下,将通过在主源集的输出中查找具有方法的类来自动配置可执行存档的主类。public static void main(String[])spring-doc.cn

也可以使用 task 的属性显式配置 main 类:mainClassspring-doc.cn

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

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

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

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

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

最后,可以在任务清单上配置该属性:Start-Classspring-doc.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 类的名称。 例如,变为 . 如果使用定义了另一个名称,则应使用该名称。KtExampleApplicationExampleApplicationKt@JvmName

包括仅限开发的依赖项

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

如果要在存档中包含配置中声明的依赖项,请配置其任务的 Classpath 以包含配置,如下面的任务示例所示:developmentOnlybootWarspring-doc.cn

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

配置需要解包的库

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

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

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

为了获得更多控制,也可以使用闭包。 闭包传递 a 并应返回 a ,指示是否需要解包。FileTreeElementbooleanspring-doc.cn

使归档文件完全可执行

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

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

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

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

这会将 Spring Boot 的默认启动脚本添加到存档中。 默认启动脚本包括多个具有合理默认值的属性。 可以使用以下属性自定义这些值:propertiesspring-doc.cn

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

如果默认启动脚本不能满足您的需求,则可以使用该属性来提供自定义启动脚本:scriptspring-doc.cn

tasks.named("bootJar") {
	launchScript {
		script = file('src/custom.script')
	}
}
tasks.named<BootJar>("bootJar") {
	launchScript {
		script = file("src/custom.script")
	}
}

使用 PropertiesLauncher

要使用 来启动可执行的 jar 或 war,请配置任务的清单以设置属性:PropertiesLauncherMain-Classspring-doc.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")
	}
}

打包分层 Jar 或 War

默认情况下,该任务会构建一个存档,该存档分别包含 和 中的应用程序类和依赖项。 同样,构建一个存档,其中包含应用程序的类 in 和 和 中的依赖项。 对于需要从 jar 的内容构建 docker 镜像的情况,能够进一步分离这些目录以便将它们写入不同的层非常有用。bootJarBOOT-INF/classesBOOT-INF/libbootWarWEB-INF/classesWEB-INF/libWEB-INF/lib-providedspring-doc.cn

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

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

  • dependencies对于其版本不包含 .SNAPSHOTspring-doc.cn

  • spring-boot-loader对于 jar 加载器类。spring-doc.cn

  • snapshot-dependencies对于其版本包含 .SNAPSHOTspring-doc.cn

  • application对于项目依赖项、应用程序类和资源。spring-doc.cn

层顺序非常重要,因为它决定了当应用程序的一部分发生更改时,可以缓存先前层的可能性。 默认顺序为 , , , 。 应首先添加最不可能更改的内容,然后添加更有可能更改的图层。dependenciesspring-boot-loadersnapshot-dependenciesapplicationspring-doc.cn

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

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

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

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

自定义图层配置

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

这可以使用描述如何将 jar 或 war 分成层以及这些层的顺序的配置来完成。 以下示例显示了如何显式定义上述默认 Sequences:spring-doc.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"))
	}
}

DSL 由三个部分定义:layeredspring-doc.cn

  • 闭包定义了应用程序类和资源的分层方式。applicationspring-doc.cn

  • 闭包定义了依赖项应该如何分层。dependenciesspring-doc.cn

  • 该方法定义层的写入顺序。layerOrderspring-doc.cn

嵌套闭包在 和 部分中用于声明图层的内容。 这些 Closure 按照定义的顺序从上到下进行评估。 任何未被先前的 closure 认领的内容仍可供后续 CLOSED 考虑。intoLayerapplicationdependenciesintoLayerspring-doc.cn

闭包使用 nested 和 调用来声明内容。 闭包对包含/排除参数使用 Ant 样式的路径匹配。 该部分使用模式。 它还提供了可用于包含或排除项目依赖项的方法。intoLayerincludeexcludeapplicationdependenciesgroup:artifact[:version]includeProjectDependencies()excludeProjectDependencies()spring-doc.cn

如果未进行调用,则考虑所有内容(未由较早的闭包声明)。includespring-doc.cn

如果未进行调用,则不会应用任何排除项。excludespring-doc.cn

查看上面示例中的闭包,我们可以看到第一个闭包将声明该层的所有项目依赖项。 下一个将声明该层的所有 SNAPSHOT 依赖项。 第三个也是最后一个将声明层的剩余任何内容(在本例中为非项目依赖项或 SNAPSHOT 的任何依赖项)。dependenciesintoLayerapplicationintoLayersnapshot-dependenciesintoLayerdependenciesspring-doc.cn

闭包也有类似的规则。 首先声明图层的内容。 然后声明该层的所有剩余类和资源。applicationorg/springframework/boot/loader/**spring-boot-loaderapplicationspring-doc.cn

闭包的添加顺序通常与层的写入顺序不同。 因此,必须始终调用该方法,并且必须涵盖调用引用的所有层。intoLayerlayerOrderintoLayer