跳到主要内容

构建

DeepSeek V3 中英对照 Build

Spring Boot 包含了适用于 Maven 和 Gradle 的构建插件。本节将回答有关这些插件的常见问题。

生成构建信息

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

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.4.2</version>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
xml
提示

更多详情请参阅 Spring Boot Maven 插件文档

以下示例使用 Gradle 实现了相同的功能:

springBoot {
buildInfo()
}
gradle
提示

更多详情请参阅 Spring Boot Gradle 插件文档

生成 Git 信息

Maven 和 Gradle 都允许生成一个包含项目构建时 git 源代码仓库状态信息的 git.properties 文件。

对于 Maven 用户,spring-boot-starter-parent POM 包含一个预配置的插件来生成 git.properties 文件。要使用它,请在你的 POM 中添加以下 Git Commit Id Plugin 声明:

<build>
<plugins>
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
xml

Gradle 用户可以通过使用 gradle-git-properties 插件来实现相同的效果,如下例所示:

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

Maven 和 Gradle 插件都允许配置包含在 git.properties 中的属性。

提示

git.properties 中的提交时间预期符合以下格式:yyyy-MM-dd’T’HH:mm:ssZ。这是上述两个插件的默认格式。使用此格式可以将时间解析为 Date,并且在序列化为 JSON 时,其格式可以通过 Jackson 的日期序列化配置设置来控制。

生成 CycloneDX SBOM

Maven 和 Gradle 都允许在项目构建时生成 CycloneDX SBOM。

对于 Maven 用户来说,spring-boot-starter-parent POM 包含了一个预配置的插件来生成 SBOM。要使用它,请在您的 POM 中添加以下 cyclonedx-maven-plugin 的声明:

<build>
<plugins>
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
xml

Gradle 用户可以通过使用 cyclonedx-gradle-plugin 插件来实现相同的结果,如下例所示:

plugins {
id 'org.cyclonedx.bom' version '1.10.0'
}
gradle

自定义依赖版本

spring-boot-dependencies POM 管理着常见依赖的版本。Maven 和 Gradle 的 Spring Boot 插件允许通过构建属性来自定义这些管理的依赖版本。

注意

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

要使用 Maven 覆盖依赖版本,请参阅 Maven 插件文档中的使用插件

要覆盖 Gradle 中的依赖版本,请参阅 Gradle 插件文档中的自定义托管版本

使用 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>
xml

如果不使用父级 POM,你仍然可以使用该插件。但是,你必须额外添加一个 <executions> 部分,如下所示:

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.4.2</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
xml

请参阅插件文档以获取完整的使用详情。

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

与 war 文件类似,Spring Boot 应用程序并不适合作为依赖项使用。如果你的应用程序包含希望与其他项目共享的类,推荐的做法是将这些代码移至一个单独的模块中。然后,你的应用程序和其他项目可以依赖这个单独的模块。

如果无法按照上述建议重新组织代码,则必须配置 Spring Boot 的 Maven 和 Gradle 插件以生成适合用作依赖项的独立构件。可执行归档文件不能用作依赖项,因为可执行 jar 格式将应用程序类打包在 BOOT-INF/classes 中。这意味着当可执行 jar 用作依赖项时,这些类将无法被找到。

为了生成两个构件,一个可作为依赖项使用,另一个是可执行的构件,必须指定一个分类器(classifier)。此分类器将应用于可执行归档文件的名称,而默认的归档文件则保留为依赖项使用。

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

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

提取特定库文件当可执行 Jar 运行时

大多数嵌套在可执行 jar 包中的库在运行时不需要被解压。然而,某些库可能会出现问题。例如,JRuby 包含其自身的嵌套 jar 支持,该支持假设 jruby-complete.jar 始终可以直接作为一个独立的文件使用。

为了处理任何有问题的库,你可以标记特定的嵌套 jars,使得它们在可执行 jar 首次运行时自动解压。这些嵌套的 jars 会被写入到由 java.io.tmpdir 系统属性标识的临时目录下。

注意

请注意,需确保您的操作系统配置得当,以避免在应用程序仍在运行时删除已解压到临时目录中的 jar 文件。

例如,要指示 JRuby 应通过 Maven 插件标记为解包,您需要添加以下配置:

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

创建一个排除依赖的非可执行 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>
xml

使用 Maven 启动的 Spring Boot 应用程序的远程调试

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

有关更多详细信息,请参阅此示例

从 Ant 构建可执行归档文件而不使用 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)。请记住 不要 压缩归档中的条目。

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

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

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