Build

Spring Boot 包含用于 Maven 和 Gradle 的构建插件。此部分回答了关于这些插件的常见问题。

Generate Build Information

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

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

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

有关更多详细信息,请参阅 Spring Boot Maven Plugin documentation

以下示例使用 Gradle 执行相同的任务:

springBoot {
	buildInfo()
}

有关更多详细信息,请参阅 Spring Boot Gradle Plugin documentation

Generate Git Information

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

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

<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 日期序列化配置设置控制。

Customize Dependency Versions

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

每个 Spring Boot 版本根据这些特定第三方依赖进行设计和测试。覆盖版本可能会导致兼容性问题。

要覆盖 Maven 中的依赖版本,请参阅 this sectionMaven 插件文档。

要覆盖 Gradle 中的依赖版本,请参阅 this sectionGradle 插件文档。

Create an Executable JAR with Maven

spring-boot-maven-plugin 可以用来创建一个可执行的 “fat” 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>{version-spring-boot}</version>
			<executions>
				<execution>
					<goals>
						<goal>repackage</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

有关完整的使用详情,请参见 plugin documentation

Use a Spring Boot Application as a Dependency

Spring Boot 应用程序不能像 war 文件一样被用作依赖项。如果你的应用程序包含你想与其他项目共享的类,则推荐的做法是将该代码迁入一个独立的模块。然后,独立的模块由你的应用程序和其他项目所依赖。

如果你不能按照上述建议重新安排你的代码,则必须配置 Spring Boot 的 Maven 和 Gradle 插件以生成适合用作依赖项的独立制品。可执行归档不能用作依赖项,因为 executable jar formatBOOT-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>

Extract Specific Libraries When an Executable Jar Runs

可执行 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>

Create a Non-executable JAR with Exclusions

通常,如果你有可执行 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>

Remote Debug a Spring Boot Application Started with Maven

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

有关更多详细信息,请参阅 this example

Build an Executable Archive From Ant without Using 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)。记住 not 压缩存档中的条目。

  3. provided(嵌入式容器)依赖项添加到嵌套 BOOT-INF/lib 目录(用于 jar)或 WEB-INF/lib-provided 目录(用于 war)。记住 not 压缩存档中的条目。

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

  5. 使用适当的启动程序(例如 JarLauncher,用于 jar 文件)作为清单中的 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>