构建

Spring Boot 包含 Maven 和 Gradle 的构建插件。本节回答有关这些插件的常见问题。

生成构建信息

Maven 插件和 Gradle 插件都允许生成构建信息,其中包含项目的坐标、名称和版本。这些插件还可以配置为通过配置添加其他属性。当存在此类文件时,Spring Boot 会自动配置一个 BuildProperties bean。

要使用 Maven 生成构建信息,请添加 build-info 目标的执行,如以下示例所示

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<version>3.3.0</version>
			<executions>
				<execution>
					<goals>
						<goal>build-info</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>
有关更多详细信息,请参阅 Spring Boot Maven 插件文档

以下示例使用 Gradle 完成相同操作

springBoot {
	buildInfo()
}
有关更多详细信息,请参阅 Spring Boot Gradle 插件文档

生成 Git 信息

Maven 和 Gradle 都允许生成一个 git.properties 文件,其中包含项目构建时 git 源代码存储库状态的信息。

对于 Maven 用户,spring-boot-starter-parent POM 包含一个预配置的插件来生成 git.properties 文件。要使用它,请将以下声明添加到您的 POM 中,用于 Git Commit Id Plugin

<build>
	<plugins>
		<plugin>
			<groupId>io.github.git-commit-id</groupId>
			<artifactId>git-commit-id-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

Gradle 用户可以使用 gradle-git-properties 插件来实现相同的结果,如下例所示

plugins {
	id "com.gorylenko.gradle-git-properties" version "2.4.1"
}

Maven 和 Gradle 插件都允许配置 git.properties 中包含的属性。

git.properties 中的提交时间应与以下格式匹配:yyyy-MM-dd’T’HH:mm:ssZ。这是上面列出的两个插件的默认格式。使用此格式可以让时间解析为 Date,并且其格式在序列化为 JSON 时受 Jackson 的日期序列化配置设置控制。

自定义依赖项版本

spring-boot-dependencies POM 管理常用依赖项的版本。Maven 和 Gradle 的 Spring Boot 插件允许使用构建属性自定义这些管理的依赖项版本。

每个 Spring Boot 版本都针对此特定的一组第三方依赖项进行设计和测试。覆盖版本可能会导致兼容性问题。

要使用 Maven 覆盖依赖项版本,请参阅 Maven 插件文档的 本节

要覆盖 Gradle 中的依赖项版本,请参阅 Gradle 插件文档的 本节

使用 Maven 创建可执行 JAR

spring-boot-maven-plugin 可用于创建可执行的“胖”JAR。如果您使用 spring-boot-starter-parent POM,则可以声明插件,并且您的 jar 将重新打包如下

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

如果您不使用父 POM,您仍然可以使用该插件。但是,您必须另外添加一个<executions>部分,如下所示

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<version>3.3.0</version>
			<executions>
				<execution>
					<goals>
						<goal>repackage</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

有关完整的使用说明,请参阅插件文档

将 Spring Boot 应用程序用作依赖项

与 war 文件类似,Spring Boot 应用程序不打算用作依赖项。如果您的应用程序包含您想与其他项目共享的类,建议的方法是将该代码移到一个单独的模块中。然后,您的应用程序和其他项目可以依赖于该单独的模块。

如果您无法按上述建议重新排列代码,则必须配置 Spring Boot 的 Maven 和 Gradle 插件以生成适合用作依赖项的单独工件。可执行存档不能用作依赖项,因为可执行 jar 格式将应用程序类打包在BOOT-INF/classes中。这意味着当可执行 jar 用作依赖项时,它们将无法找到。

要生成两个工件,一个可以用作依赖项,另一个是可执行的,必须指定一个分类器。此分类器将应用于可执行存档的名称,保留默认存档以用作依赖项。

要在 Maven 中配置exec分类器,您可以使用以下配置

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<classifier>exec</classifier>
			</configuration>
		</plugin>
	</plugins>
</build>

在可执行 jar 运行时提取特定库

可执行 jar 中的大多数嵌套库不需要解压缩才能运行。但是,某些库可能会出现问题。例如,JRuby 包含它自己的嵌套 jar 支持,它假设jruby-complete.jar始终作为它自己的文件直接可用。

为了处理任何有问题的库,您可以标记特定嵌套 jar 应该在可执行 jar 首次运行时自动解压缩。此类嵌套 jar 写在由java.io.tmpdir系统属性标识的临时目录之下。

应注意确保您的操作系统已配置,以便在应用程序仍在运行时不会删除已解压缩到临时目录的 jar。

例如,要指示使用 Maven 插件将 JRuby 标记为解压缩,您需要添加以下配置

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<requiresUnpack>
					<dependency>
						<groupId>org.jruby</groupId>
						<artifactId>jruby-complete</artifactId>
					</dependency>
				</requiresUnpack>
			</configuration>
		</plugin>
	</plugins>
</build>

创建不带执行权限的 JAR 文件,并排除某些文件

通常,如果您有两个独立的构建产品,一个可执行的 JAR 文件和一个不可执行的 JAR 文件,那么可执行版本将包含库 JAR 文件中不需要的额外配置文件。例如,application.yaml 配置文件可能会从不可执行的 JAR 文件中排除。

在 Maven 中,可执行 JAR 文件必须是主工件,您可以添加一个分类 JAR 文件作为库,如下所示

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
		<plugin>
			<artifactId>maven-jar-plugin</artifactId>
			<executions>
				<execution>
					<id>lib</id>
					<phase>package</phase>
					<goals>
						<goal>jar</goal>
					</goals>
					<configuration>
						<classifier>lib</classifier>
						<excludes>
							<exclude>application.yaml</exclude>
						</excludes>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

使用 Maven 启动的 Spring Boot 应用程序进行远程调试

要将远程调试器附加到使用 Maven 启动的 Spring Boot 应用程序,您可以使用 maven 插件jvmArguments 属性。

有关更多详细信息,请参阅 此示例

使用 Ant 构建可执行存档,不使用 spring-boot-antlib

要使用 Ant 构建,您需要获取依赖项、编译,然后创建 JAR 或 WAR 存档。要使其可执行,您可以使用 spring-boot-antlib 模块,也可以按照以下说明操作

  1. 如果您正在构建 JAR 文件,请将应用程序的类和资源打包到嵌套的 BOOT-INF/classes 目录中。如果您正在构建 WAR 文件,请将应用程序的类打包到嵌套的 WEB-INF/classes 目录中,就像往常一样。

  2. 将运行时依赖项添加到嵌套的 BOOT-INF/lib 目录中(对于 JAR 文件)或 WEB-INF/lib 目录中(对于 WAR 文件)。请记住,**不要**压缩存档中的条目。

  3. provided(嵌入式容器)依赖项添加到嵌套的 BOOT-INF/lib 目录中(对于 JAR 文件)或 WEB-INF/lib-provided 目录中(对于 WAR 文件)。请记住,**不要**压缩存档中的条目。

  4. spring-boot-loader 类添加到存档的根目录(以便 Main-Class 可用)。

  5. 使用适当的启动器(例如,对于 JAR 文件,使用 JarLauncher)作为清单中的 Main-Class 属性,并指定它需要的其他属性作为清单条目,主要通过设置 Start-Class 属性。

以下示例展示了如何使用 Ant 构建可执行存档

<target name="build" depends="compile">
	<jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
		<mappedresources>
			<fileset dir="target/classes" />
			<globmapper from="*" to="BOOT-INF/classes/*"/>
		</mappedresources>
		<mappedresources>
			<fileset dir="src/main/resources" erroronmissingdir="false"/>
			<globmapper from="*" to="BOOT-INF/classes/*"/>
		</mappedresources>
		<mappedresources>
			<fileset dir="${lib.dir}/runtime" />
			<globmapper from="*" to="BOOT-INF/lib/*"/>
		</mappedresources>
		<zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
		<manifest>
			<attribute name="Main-Class" value="org.springframework.boot.loader.launch.JarLauncher" />
			<attribute name="Start-Class" value="${start-class}" />
		</manifest>
	</jar>
</target>