91. Build

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

91.1 生成内部版本信息

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

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

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

Tip

有关更多详细信息,请参见Spring Boot Maven 插件文档

下面的示例对 Gradle 执行相同的操作:

springBoot {
	buildInfo()
}

Tip

有关更多详细信息,请参见Spring Boot Gradle 插件文档

91.2 生成 Git 信息

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

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

<build>
	<plugins>
		<plugin>
			<groupId>pl.project13.maven</groupId>
			<artifactId>git-commit-id-plugin</artifactId>
		</plugin>
	</plugins>
</build>

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

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

Tip

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

91.3 自定义依赖关系版本

如果您使用的 Maven 构建直接或间接继承自spring-boot-dependencies(例如spring-boot-starter-parent),但是要覆盖特定的第三方依赖关系,则可以添加适当的<properties>元素。浏览spring-boot-dependencies POM 以获取完整的属性列表。例如,要选择其他slf4j版本,您可以添加以下属性:

<properties>
	<slf4j.version>1.7.5<slf4j.version>
</properties>

Note

仅当您的 Maven 项目(直接或间接)继承spring-boot-dependencies时,此方法才有效。如果您在自己的dependencyManagement部分中使用<scope>import</scope>添加了spring-boot-dependencies,则必须自己重新定义工件,而不是覆盖该属性。

Warning

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

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

91.4 使用 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>2.1.1.RELEASE</version>
			<executions>
				<execution>
					<goals>
						<goal>repackage</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

有关完整用法的详细信息,请参见plugin documentation

91.5 使用 Spring Boot 应用程序作为依赖项

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

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

为了产生两个工件,一个可以用作依赖项,另一个可以执行,必须指定分类器。该分类器应用于可执行 Files 的名称,保留默认 Files 作为依赖项。

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

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

91.6 运行可执行 jar 时提取特定的库

可执行 jar 中的大多数嵌套库无需解压缩即可运行。但是,某些库可能会有问题。例如,JRuby 包括其自己的嵌套 jar 支持,它假定jruby-complete.jar始终可以直接作为文件直接使用。

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

Warning

应注意确保已配置 os,以便在应用程序仍在运行时不会删除已解压缩到临时目录中的 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>

91.7 创建带有排除项的不可执行的 JAR

通常,如果您具有一个可执行文件和一个不可执行的 jar 作为两个单独的构建产品,则可执行版本具有库 jar 中不需要的其他配置文件。例如,application.yml配置文件可能被排除在不可执行的 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.yml</exclude>
						</excludes>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

91.8 远程调试以 Maven 开头的 Spring Boot 应用程序

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

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

91.9 无需使用 spring-boot-antlib 就可以从 Ant 构建可执行存档

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

  • 如果要构建 jar,请将应用程序的类和资源打包在嵌套的BOOT-INF/classes目录中。如果要发动 War,请照常将应用程序的类打包在嵌套的WEB-INF/classes目录中。

  • 在 jar 的嵌套BOOT-INF/lib目录中或在 war 的WEB-INF/lib中添加运行时依赖项。记住不要压缩压缩 Files 中的条目。

  • 在 jar 的嵌套BOOT-INF/lib目录中添加provided(嵌入式容器)依赖项,对于 War 则在WEB-INF/lib-provided中添加。记住不要压缩压缩 Files 中的条目。

  • 在 Files 的根目录中添加spring-boot-loader类(以便Main-Class可用)。

  • 使用适当的启动器(例如 jar 文件的JarLauncher)作为 Lists 中的Main-Class属性,并通过设置Start-Class属性来指定它作为 Lists 条目所需的其他属性。

以下示例显示了如何使用 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.JarLauncher" />
			<attribute name="Start-Class" value="${start-class}" />
		</manifest>
	</jar>
</target>

Ant Sample包含一个build.xml文件,该文件具有manual任务,如果使用以下命令运行该文件,该任务应该可以工作:

$ ant -lib <folder containing ivy-2.2.jar> clean manual

然后,您可以使用以下命令运行该应用程序:

$ java -jar target/*.jar