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

打包可执行 Jar

可以使用该任务构建可执行 jar。 该任务是在应用插件时自动创建的,并且是 BootJar 的实例。 任务会自动配置为依赖于任务,因此运行(或)也将运行该任务。bootJarjavaassemblebootJarassemblebuildbootJarSpring中文文档

打包可执行文件大战

可以使用该任务构建可执行战争。 该任务是在应用插件时自动创建的,并且是 BootWar 的实例。 任务会自动配置为依赖于任务,因此运行(或)也将运行该任务。bootWarwarassemblebootWarassemblebuildbootWarSpring中文文档

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

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

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中文文档

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

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

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

如果您希望可执行存档(而不是普通存档)使用分类器,请为 and 任务配置分类器,如以下示例所示:jarbootJarSpring中文文档

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

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

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

或者,如果您希望根本不构建普通存档,请禁用其任务,如以下任务示例所示:jarSpring中文文档

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

配置可执行存档打包

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

配置主类

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

还可以使用任务的属性显式配置主类:mainClassSpring中文文档

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

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

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

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

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

最后,可以在任务清单上配置该属性:Start-ClassSpring中文文档

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中文文档

如果要在归档文件中包含配置中声明的依赖项,请将其任务的类路径配置为包含配置,如以下任务示例所示:developmentOnlybootWarSpring中文文档

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

配置需要解压缩的库

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

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

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

为了更好地控制,还可以使用闭合器。 闭合传递 a,并应返回 a,指示是否需要拆包。FileTreeElementbooleanSpring中文文档

使存档完全可执行

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

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

若要使用此功能,必须启用启动脚本的包含:Spring中文文档

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

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

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

如果默认启动脚本不能满足您的需求,则可以使用该属性来提供自定义启动脚本:scriptSpring中文文档

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

使用 PropertiesLauncher

要使用 启动可执行 jar 或 war,请配置任务的清单以设置属性:PropertiesLauncherMain-ClassSpring中文文档

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

包装分层罐或战争

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

分层 jar 使用与常规启动打包 jar 相同的布局,但包含描述每个层的附加元数据文件。Spring中文文档

默认情况下,定义以下层:Spring中文文档

图层顺序很重要,因为它决定了当应用程序的某些部分发生更改时,缓存先前图层的可能性。 默认顺序为 、 、 、 。 应首先添加最不可能更改的内容,然后添加更有可能更改的内容。dependenciesspring-boot-loadersnapshot-dependenciesapplicationSpring中文文档

要禁用此功能,您可以通过以下方式执行此操作:Spring中文文档

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

创建分层 jar 或战争时,jar 将作为依赖项添加到您的存档中。 在类路径上使用此 jar,您可以在特殊模式下启动应用程序,该模式允许引导代码运行与应用程序完全不同的内容,例如,提取层的内容。 如果要排除此依赖关系,可以通过以下方式执行此操作:spring-boot-jarmode-toolsSpring中文文档

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

自定义图层配置

根据您的应用程序,您可能需要调整图层的创建方式并添加新图层。Spring中文文档

这可以使用描述如何将 jar 或 war 分成层以及这些层的顺序的配置来完成。 以下示例演示如何显式定义上述默认排序:Spring中文文档

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中文文档

嵌套闭包在 和 部分内用于声明图层的内容。 这些闭包按照定义顺序从上到下进行评估。 任何未在早期关闭中声明的内容仍可供后续关闭者考虑。intoLayerapplicationdependenciesintoLayerSpring中文文档

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

如果没有进行调用,则考虑所有内容(未在较早关闭时声明)。includeSpring中文文档

如果未进行调用,则不会应用任何排除项。excludeSpring中文文档

查看上面示例中的闭包,我们可以看到第一个闭包将声明该层的所有项目依赖项。 接下来将声明该层的所有 SNAPSHOT 依赖项。 第三个也是最后一个将声明图层的剩余任何内容(在本例中,任何不是项目依赖项或 SNAPSHOT 的依赖项)。dependenciesintoLayerapplicationintoLayersnapshot-dependenciesintoLayerdependenciesSpring中文文档

关闭也有类似的规则。 首先声明图层的内容。 然后声明图层的任何剩余类和资源。applicationorg/springframework/boot/loader/**spring-boot-loaderapplicationSpring中文文档

添加闭包的顺序通常与写入层的顺序不同。 因此,必须始终调用该方法,并且必须覆盖调用引用的所有层。intoLayerlayerOrderintoLayer
如果主类是用 Kotlin 编写的,则应使用生成的 Java 类的名称。 默认情况下,这是添加了后缀的 Kotlin 类的名称。 例如,变为 . 如果定义了另一个名称,则应使用该名称。KtExampleApplicationExampleApplicationKt@JvmName
目前,某些工具不接受此格式,因此您可能并不总是能够使用此技术。 例如,可能会默默地无法提取已完全可执行的 jar 或 war。 建议仅在打算直接执行此选项时才启用此选项,而不是与 Servlet 容器一起运行或将其部署到 Servlet 容器。jar -xfjava -jar
添加闭包的顺序通常与写入层的顺序不同。 因此,必须始终调用该方法,并且必须覆盖调用引用的所有层。intoLayerlayerOrderintoLayer