本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

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

1. Spring Boot Maven 插件

Spring Boot Maven插件在Maven中提供了对Spring Boot的支持,让你可以打包可执行的jar或war文件,并 "就地" 运行一个应用程序。 要使用它,你必须使用Maven 3.6.3(或更高版本)。

请参阅该插件的文档以了解更多。

2. Spring Boot Gradle 插件

Spring Boot Gradle插件在Gradle中提供Spring Boot支持,让你打包可执行的jar或war文件,运行Spring Boot应用程序,并使用 spring-boot-dependencies 提供的依赖管理。 它需要Gradle 7.x(7.5或更高版本)或8.x。 参见该插件的文档以了解更多。

3. Spring Boot AntLib Module

Spring Boot AntLib模块为Apache Ant提供基本的Spring Boot支持。 你可以使用该模块来创建可执行的jars。 要使用该模块,你需要在你的 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-3.2.0-SNAPSHOT.jar>
在 "使用Spring Boot" 一节中,有一个更完整的使用Apache Ant与spring-boot-antlib的例子。

3.1. Spring Boot Ant Task

一旦 spring-boot-antlib 命名空间被声明,下列额外的任务就可以使用。

3.1.1. 使用 “exejar” Task

你可以使用 exejar 任务来创建一个Spring Boot可执行的jar。 该任务支持以下属性。

属性 说明 必须

destfile

要创建的目标jar文件

Yes

classes

Java类文件的根目录

Yes

start-class

要运行的主要main application类

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

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

元素 说明

resources

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

lib

一个或多个 资源集合,应该被添加到构成应用程序运行时依赖classpath的jar库集合中。

3.1.2. 示例

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

Specify 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>
Detect start-class
<exejar destfile="target/my-application.jar" classes="target/classes">
    <lib>
        <fileset dir="lib" />
    </lib>
</exejar>

3.2. 使用 “findmainclass” Task

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

属性 说明 必须

classesroot

Java类文件的根目录

yes (除非指定了 mainclass

mainclass

可用于缩短 main class 的搜索时间

No

property

应该用结果设置的Ant属性

No (如果没有指定,结果将被记录下来)

3.2.1. 示例

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

Find and log
<findmainclass classesroot="target/classes" />
Find and set
<findmainclass classesroot="target/classes" property="main-class" />
Override and set
<findmainclass mainclass="com.example.MainClass" property="main-class" />

4. 支持其他构建系统

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

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

4.1. 重新打包归档文件

要重新包装一个现有的归档文件,使其成为一个独立的可执行归档文件,请使用 org.springframework.boot.loader.tools.RepackagerRepackager 类需要一个构造参数,该参数指的是现有的jar或war归档。 使用两个可用的 repackage() 方法之一来替换原始文件或写到一个新的目的地。 在运行前,还可以在重新打包器上配置各种设置。

4.2. 嵌套库

当重新打包一个归档文件时,你可以通过使用 org.springframework.boot.loader.tools.Libraries 接口包括对依赖性文件的引用。 我们在此不提供任何 Libraries 的具体实现,因为它们通常是针对构建系统的。

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

4.3. 找到 Main Class

如果你不使用 Repackager.setMainClass() 来指定一个主类,Repackager会使用 ASM 来读取类文件,并尝试用 public static void main(String[] args) 方法找到一个合适的类。如果发现有多个候选类,就会抛出一个异常。

4.4. 实现重新打包的实例

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

Java
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 ...
    }

}
Kotlin
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
import java.io.File
import java.io.IOException

class MyBuildTool {

    @Throws(IOException::class)
    fun build() {
        val sourceJarFile: File? =  ...
        val repackager = Repackager(sourceJarFile)
        repackager.setBackupSource(false)
        repackager.repackage { callback: LibraryCallback -> getLibraries(callback) }
    }

    @Throws(IOException::class)
    private fun getLibraries(callback: LibraryCallback) {
        // Build system specific implementation, callback for each dependency
        for (nestedJar in getCompileScopeJars()!!) {
            callback.library(Library(nestedJar, LibraryScope.COMPILE))
        }
        // ...
    }

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

}

5. 接下来读取什么

如果你对构建工具插件的工作方式感兴趣,你可以看看GitHub上的 spring-boot-tools 模块。更多关于可执行jar格式的技术细节将在附录中介绍。

如果你有具体的构建相关问题,请看 “how-to” 指南。