章节 VIII. 构建工具插件

Spring Boot 为 Maven 和 Gradle 提供了构建工具插件。插件提供了各种特性,包括可执行 jar 的封装。本节提供了两个插件的更多细节,以及扩展一个不受支持的构建系统所需的一些帮助。如果你刚刚开始,可能希望首先阅读 “章节 III, “使用 Spring Boot”” 部分中的 “小节 13, 构建系统”。

69. Spring Boot Maven 插件

Spring Boot Maven 插件 在 Maven 中提供 Spring Boot 支持,允许你打包可执行的 jar 或 war 存档,并在位置上运行一个应用程序。要使用它,必须使用 Maven 3.2(或更高版本)。

[Note] Note

请参阅 Spring Boot Maven 插件网站以获取完整的插件文档。

69.1 包含 Plugin

要使用 Spring Boot Maven 插件,请在 pom.xml 的 plugins 部分中包含适当的 XML,如下面的示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!-- ... -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.1.0.BUILD-SNAPSHOT</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

前面的配置重新包装了在 Maven 生命周期的 package 阶段期间构建的 jar 或 war。下面的示例既展示了重新打包的 jar,也展示了 target 目录中的原始jar:

$ mvn package
$ ls target/*.jar
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original

如果不包含 <execution/> 配置,如前面的示例所示,你可以自己运行插件(但只有在使用打包目标的情况下),如下面的示例所示:

$ mvn package spring-boot:repackage
$ ls target/*.jar
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original

如果使用里程碑或快照版本,还需要添加适当的 pluginRepository 元素,如下面的清单所示:

<pluginRepositories>
	<pluginRepository>
		<id>spring-snapshots</id>
		<url>https://repo.spring.io/snapshot</url>
	</pluginRepository>
	<pluginRepository>
		<id>spring-milestones</id>
		<url>https://repo.spring.io/milestone</url>
	</pluginRepository>
</pluginRepositories>

69.2 打包可执行 Jar 和 War 文件

一旦 spring-boot-maven-plugin 被包含在 pom.xml 中,它就会自动尝试重写归档文件,以使它们能够通过使用 spring-boot:repackage 目标来执行。你应该使用通常的 packaging 元素来配置项目来构建(适当地)jar 或 war,如下面的示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<!-- ... -->
	<packaging>jar</packaging>
	<!-- ... -->
</project>

在打包阶段,Spring Boot 增强了现有的存档。要启动的主类可以通过使用配置选项或通过以通常的方式向清单添加 Main-Class 属性来指定。如果未指定主类,则插件搜索具有 public static void main(String[] args) 方法的类。

若要生成并运行项目存档,可以键入以下内容:

$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.jar

为了构建既可执行又可部署到外部容器中的 war 文件,需要将嵌入式容器依赖项标记为 “provided”,如下例所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<!-- ... -->
	<packaging>war</packaging>
	<!-- ... -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- ... -->
	</dependencies>
</project>
[Tip] Tip

请参阅 “小节 89.1, “创建可部署的 war 文件”” 部分,以了解如何创建可部署的 war 文件的更多细节。

高级配置选项和示例可在插件信息页中找到。

70. Spring Boot Gradle 插件

Spring Boot Gradle 插件在 Gradle 中提供了 Spring Boot 支持,允许你打包可执行 jar 或 war 归档,运行 Spring Boot 应用程序,并使用 spring-boot-dependencies 提供的依赖项管理。它需要 Gradle 4.0 或更高。请参考插件的文档以了解更多内容:

  • 参考文档 (HTML 和 PDF)
  • API

71. Spring Boot AntLib 模块

Spring Boot AntLib 模块为 Apache Ant 提供基本的 Spring Boot 支持。可以使用该模块创建可执行的 jar。要使用该模块,你需要在 build.xml 中声明一个附加的 spring-boot 命名空间,如下面的示例所示:

<project xmlns:ivy="antlib:org.apache.ivy.ant"
	xmlns:spring-boot="antlib:org.springframework.boot.ant"
	name="myapp" default="build">
	...
</project>

你需要记住使用 -lib 选项启动 Ant,如下面的示例所示:

$ ant -lib <folder containing spring-boot-antlib-2.1.0.BUILD-SNAPSHOT.jar>
[Tip] Tip

“使用 Spring Boot” 部分包括用 spring-boot-antlib 使用 Apache Ant 的一个更完整的例子。

71.1 Spring Boot Ant 任务

一旦声明了 spring-boot-antlib 命名空间,就有下列附加任务:

  • 小节 71.1.1, “spring-boot:exejar”
  • 小节 71.2, “spring-boot:findmainclass”

71.1.1 spring-boot:exejar

可以使用 exejar 任务创建 Spring Boot 可执行 jar。任务支持以下属性:

属性 描述 必须

destfile

要创建的目标 jar 文件

Yes

classes

Java 类文件的根目录

Yes

start-class

要运行的主应用程序类

No (默认是第一个找到的声明 main 方法的类)

下列嵌套元素可以与任务一起使用:

元素 描述

resources

应添加到创建的 jar 文件内容的一个或多个资源集合描述的一组资源。

lib

应该添加到组成应用程序的运行时依赖项类路径的一组 jar 库中的一个或多个资源集合。

71.1.2 示例

本节展示了两个 Ant 任务的示例。

指定 start-class. 

<spring-boot:exejar destfile="target/my-application.jar"
		classes="target/classes" start-class="com.example.MyApplication">
	<resources>
		<fileset dir="src/main/resources" />
	</resources>
	<lib>
		<fileset dir="lib" />
	</lib>
</spring-boot:exejar>

检测 start-class. 

<exejar destfile="target/my-application.jar" classes="target/classes">
	<lib>
		<fileset dir="lib" />
	</lib>
</exejar>

71.2 spring-boot:findmainclass

exejar 内部使用 findmainclass 任务来定位声明 main 的类。如果需要,你也可以直接在你的构建中使用此任务。支持以下属性:

属性 描述 必须

classesroot

Java 类文件的根目录

Yes (除非指定了 mainclass)

mainclass

可以用来缩短 main 类的搜索

No

property

应该用结果设置的 Ant 属性

No (如果未指定,将记录结果)

71.2.1 示例

本节包含使用 findmainclass 的三个示例。

查找并记录。 

<findmainclass classesroot="target/classes" />

查找并设置。 

<findmainclass classesroot="target/classes" property="main-class" />

重写并设置。 

<findmainclass mainclass="com.example.MainClass" property="main-class" />

72. 支持其它构建系统

如果你想使用除了 Maven、Gradle 或 Ant 之外的构建工具,你可能需要开发自己的插件。可执行 jar 需要遵循特定的格式,某些条目需要以未压缩的形式编写(有关的详细信请参阅附录中的 “可执行 jar 格式” 部分)。

Spring Boot Maven 和 Gradle 插件都使用 spring-boot-loader-tools 来实际生成 jar。如果需要,可以直接使用此库。

72.1 重新打包归档

要重新打包现有存档,使其成为自包含的可执行存档,请使用 org.springframework.boot.loader.tools.Repackager。Repackager 类采用单个构造函数参数,引用现有的 jar 或 war 存档。使用两个可用的 repackage() 方法中的一个来替换原始文件或写入新的目的地。在运行之前,还可以在重新打包器上配置各种设置。

72.2 嵌套的库

在重新打包归档时,可以使用 org.springframework.boot.loader.tools.Libraries 接口来包含参考的依赖文件。在这里,我们不提供任何具体的 Libraries 实现,因为它们通常是构建系统特定的。

如果你的归档已经包含了库,你可以使用 Libraries.NONE。

72.3 查找一个主类

如果不使用 Repackager.setMainClass() 指定主类,则重新打包器使用 ASM 读取类文件,并尝试使用 public static void main(String[] args) 方法找到合适的类。如果发现一个以上的候选,则引发异常。

72.4 重新打包实现示例

下面的示例显示了一个典型的重新打包实现:

Repackager repackager = new Repackager(sourceJarFile);
repackager.setBackupSource(false);
repackager.repackage(new Libraries() {
			@Override
			public void doWithLibraries(LibraryCallback callback) throws IOException {
				// Build system specific implementation, callback for each dependency
				// callback.library(new Library(nestedFile, LibraryScope.COMPILE));
			}
		});

73. 后续内容

如果你对构建工具插件如何工作感兴趣,您可以查看 GitHub 上的 spring-boot-tools 模块。附录中涵盖了可执行 jar 格式的更多技术细节。

如果你有特定的与构建相关的问题,您可以查看 “how-to” 指南。