# 构建工具插件

Spring Boot 为 Maven 和 Gradle 提供了构建工具插件。这些插件提供了各种特性,包括可执行 JAR 的打包。本节提供了有关这两个插件的更多详细信息,以及在需要扩展不受支持的构建系统时提供的一些帮助。如果你刚刚开始,那么你可能需要先阅读“using.html”一节中的“using.html”。

# 1.1 Spring 引导 Maven 插件

Spring boot Maven 插件在 Maven 中提供了 Spring boot 支持,允许你打包可执行文件 jar 或战争归档文件并“就地”运行应用程序。要使用它,你必须使用 Maven 3.2(或更高版本)。

查看该插件的文档以了解更多信息:

# 1.2. Spring 引导 Gradle 插件

Spring boot Gradle 插件在 Gradle 中提供 Spring 引导支持,允许你打包可执行文件 jar 或战争归档文件,运行 Spring 引导应用程序,并使用spring-boot-dependencies提供的依赖管理。它需要 Gradle 6.8、6.9 或 7.x。查看该插件的文档以了解更多信息:

# 3. Spring 启动 Antlib 模块

Spring 启动 Antlib 模块为 Apache Ant 提供了基本的 Spring 启动支持。你可以使用该模块创建可执行 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 <directory containing spring-boot-antlib-2.6.4.jar>

“使用 Spring 引导”部分包括一个更完整的[使用spring-boot-antlib的 Apache Ant 示例](使用.html#using.build-systems. Ant)。

# 3.1. Spring 引导 Ant 任务

一旦声明了spring-boot-antlib名称空间,就可以执行以下附加任务:

# 3.1.1.使用“exejar”任务

你可以使用exejar任务来创建一个 Spring 引导可执行文件 jar。该任务支持以下属性:

Attribute Description 必需的
destfile The destination jar file to create 是的
classes The root directory of Java class files 是的
start-class The main application class to run (默认值是发现的第一个类,它声明了main方法)

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

Element 说明
resources 一个或多个资源收集 (opens new window),描述一组Resources (opens new window),该集合应被添加到所创建的 jar 文件的内容中。
lib 应该将一个或多个资源收集 (opens new window)添加到构成应用程序运行时依赖项 Classpath 的 jar 库集合中。

# 3.1.2.例子

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

指定起始类

<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>

检测起始类

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

# 3.2.使用“FindMainclass”任务

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

Attribute 说明 Required
classesroot Java 类文件的根目录 Yes (unless mainclass is specified)
mainclass 可用于短路main类搜索 No
property Ant 应与结果一起设置的属性 No (result will be logged if unspecified)

# 3.2.1.例子

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

查找并记录

<findmainclass classesroot="target/classes" />

查找并设置

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

覆盖和设置

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

# 4. 支持其他构建系统

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

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

# 4.1.重新包装档案

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

# 4.2.嵌套库

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

如果你的归档文件已经包含库,那么你可以使用Libraries.NONE

# 4.3.寻找主类

如果你没有使用Repackager.setMainClass()来指定主类,那么 Repackager 将使用ASM (opens new window)来读取类文件,并尝试使用public static void main(String[] args)方法找到合适的类。如果发现一个以上的候选者,将抛出一个异常。

# 4.4.示例重新打包实现

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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.springframework.boot.loader.tools.Library;
import org.springframework.boot.loader.tools.LibraryCallback;
import org.springframework.boot.loader.tools.LibraryScope;
import org.springframework.boot.loader.tools.Repackager;

public class MyBuildTool {

    public void build() throws IOException {
        File sourceJarFile = ...
        Repackager repackager = new Repackager(sourceJarFile);
        repackager.setBackupSource(false);
        repackager.repackage(this::getLibraries);
    }

    private void getLibraries(LibraryCallback callback) throws IOException {
        // Build system specific implementation, callback for each dependency
        for (File nestedJar : getCompileScopeJars()) {
            callback.library(new Library(nestedJar, LibraryScope.COMPILE));
        }
        // ...
    }

    private List<File> getCompileScopeJars() {
        return ...
    }

}

# 5. 接下来要读什么?

如果你对构建工具插件的工作方式感兴趣,可以查看 Github 上的[spring-boot-tools](https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-tools)模块。可执行 jar 格式的更多技术细节在附录中进行了介绍。

如果你有特定的与构建相关的问题,请参阅“how-to”指南。