Ahead-of-Time Processing
Spring AOT 是一个在构建时分析你的应用程序并生成其优化版本的过程。这是在原生镜像(native image)中运行 Spring ApplicationContext 的必要步骤。
有关 Spring Boot 中 GraalVM Native Images 支持的概述,请参阅参考文档。
Spring Boot Maven 插件提供了可用于对应用程序和测试代码执行 AOT 处理的目标(goals)。
Processing Applications
要配置您的应用程序以使用此功能,请添加一个 process-aot 目标的执行,如下例所示:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
由于 BeanFactory 在构建时已完全准备就绪,条件也会在此时被评估。这与常规的 Spring Boot 应用在运行时的行为有重要区别。例如,如果你想启用或禁用某些特性,就需要配置构建时所使用的环境来实现。因此,process-aot 目标与 run goal 共享了许多属性。
使用 Native Profile
如果你使用 spring-boot-starter-parent 作为项目的 parent,可以使用 native profile 来简化构建 native image 所需的步骤。
native 配置文件配置了以下内容:
-
在项目上应用 Spring Boot Maven 插件时执行
process-aot。 -
合适的配置,以便 build-image 生成原生镜像。
-
为 Native Build Tools Maven Plugin 提供合理的默认设置,特别是:
-
确保该插件使用原始 classpath,而不是主 jar 文件,因为它无法理解我们的重打包 jar 格式。
-
验证是否有合适的 GraalVM 版本可用。
-
下载第三方可达性元数据。
-
使用原始类路径(raw classpath)意味着 native image 无法感知生成的 MANIFEST.MF 文件。如果你需要在 native image 中读取清单文件的内容(例如获取应用程序的实现版本),请配置 classesDirectory 选项以使用常规的 jar 文件。
为了从 native 配置文件中受益,代表应用程序的模块应定义两个插件,如下例所示:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
单个项目可以在命令行上触发原生镜像的生成,既可以使用 Cloud Native Buildpacks,也可以使用 Native Image Build Tools。
要在多模块项目中使用 native 配置文件,你可以对 native 配置文件进行自定义,使其调用你偏好的技术。
要在 package 阶段绑定 Cloud Native Buildpacks,请在多模块项目的根 POM 中添加以下内容:
<profile>
<id>native</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-image</id>
<goals>
<goal>build-image-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
下面的示例对 Native Build Tools 做了同样的处理:
<profile>
<id>native</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<executions>
<execution>
<id>build-image</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
一旦上述配置完成,你就可以构建你的多模块项目,并在相应的子模块中生成原生镜像,如下例所示:
$ mvn package -Pnative
“相关”子模块是指代表 Spring Boot 应用程序的模块。此类模块必须如上所述定义 Native Build Tools 和 Spring Boot 插件。
spring-boot:process-aot
org.springframework.boot:spring-boot-maven-plugin:4.0.2
在应用程序上调用 AOT 引擎。
必需参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| classesDirectory | File | ${project.build.outputDirectory} |
| generatedClasses | File | ${project.build.directory}/spring-aot/main/classes |
| generatedResources | File | ${project.build.directory}/spring-aot/main/resources |
| generatedSources | File | ${project.build.directory}/spring-aot/main/sources |
可选参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| arguments | String[] | |
| compilerArguments | String | |
| excludeGroupIds | String | |
| excludes | List | |
| includes | List | |
| jvmArguments | String | |
| mainClass | String | |
| profiles | String[] | |
| skip | boolean | false |
| systemPropertyVariables | Map |
参数详情
arguments
应被 AOT 处理考虑的应用程序参数。
arguments | |
|---|---|
| 类型 | java.lang.String[] |
| 默认值 | |
| 用户属性 | |
| 起始版本 |
classesDirectory
包含应打包到归档文件中的类和资源文件的目录。
classesDirectory | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.outputDirectory} |
| 用户属性 | |
| 起始版本 |
compilerArguments
应提供给 AOT 编译过程的参数。在命令行中,请确保将多个值用引号括起来。
compilerArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.aot.compilerArguments |
| 起始版本 |
excludeGroupIds
要排除的 groupId 名称的逗号分隔列表(精确匹配)。
excludeGroupIds | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.excludeGroupIds |
| 起始版本 | 1.1.0 |
excludes
要排除的构件定义集合。Exclude 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
excludes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.excludes |
| 起始版本 | 1.1.0 |
generatedClasses
包含生成类的目录。
generatedClasses | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/main/classes |
| 用户属性 | |
| 自版本 |
generatedResources
包含生成资源的目录。
generatedResources | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/main/resources |
| 用户属性 | |
| 起始版本 |
generatedSources
包含生成源代码的目录。
generatedSources | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/main/sources |
| 用户属性 | |
| 自 |
includes
要包含的构件定义集合。Include 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
includes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.includes |
| 自 | 1.2.0 |
jvmArguments
应与 AOT 进程关联的 JVM 参数。在命令行中,请确保将多个值用引号括起来。
jvmArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.aot.jvmArguments |
| 自版本 |
mainClass
用作 AOT 过程源的主类的名称。如果未指定,则将使用找到的第一个包含 main 方法的已编译类。
mainClass | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.aot.main-class |
| 起始版本 |
profiles
用于 AOT 处理时需考虑的 Spring 配置文件。
profiles | |
|---|---|
| 类型 | java.lang.String[] |
| 默认值 | |
| 用户属性 | |
| 起始版本 |
skip
跳过执行。
skip | |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 用户属性 | spring-boot.aot.skip |
| 起始版本 |
systemPropertyVariables
要传递给 AOT 进程的 JVM 系统属性列表。
systemPropertyVariables | |
|---|---|
| 类型 | java.util.Map |
| 默认值 | |
| 用户属性 | |
| 自从 |
Processing Tests
AOT 引擎可以应用于使用 Spring 的 Test Context Framework 的 JUnit 5 测试。这些测试由 AOT 引擎处理,然后在 native image 中执行。
当使用 maven.test.skip 属性跳过常规测试时,测试不会被处理。
与生产代码一样,spring-boot-starter-parent 定义了一个 nativeTest profile,可用于简化在 native image 中执行测试所需的步骤。
nativeTest 配置文件配置了以下内容:
-
在项目上应用 Spring Boot Maven 插件时执行
process-test-aot。 -
在项目上应用 Native Build Tools Maven Plugin 时执行
test。该执行定义了合理的默认值,特别是:-
确保插件使用原始类路径,而不是主 jar 文件,因为它无法理解我们重新打包的 jar 格式。
-
验证是否存在合适的 GraalVM 版本。
-
下载第三方可达性元数据。
-
为了从 nativeTest 配置文件中受益,代表应用程序的模块应定义两个插件,如下例所示:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
一旦上述配置在每个需要此功能的模块中都已就位,你就可以构建你的多模块项目,并在相关子模块中以原生镜像(native image)执行测试,如下例所示:
$ mvn test -PnativeTest
与应用程序 AOT 处理一样,BeanFactory 在构建时已完全准备就绪。
spring-boot:process-test-aot
org.springframework.boot:spring-boot-maven-plugin:4.0.2
在测试上运行 AOT 引擎。
必需参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| classesDirectory | File | ${project.build.outputDirectory} |
| generatedClasses | File | ${project.build.directory}/spring-aot/main/classes |
| generatedResources | File | ${project.build.directory}/spring-aot/test/resources |
| generatedSources | File | ${project.build.directory}/spring-aot/test/sources |
| generatedTestClasses | File | ${project.build.directory}/spring-aot/test/classes |
| testClassesDirectory | File | ${project.build.testOutputDirectory} |
可选参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| compilerArguments | String | |
| excludeGroupIds | String | |
| excludes | List | |
| includes | List | |
| jvmArguments | String | |
| skip | boolean | false |
| systemPropertyVariables | Map |
参数详情
classesDirectory
包含用于运行测试的类和资源文件的目录。
classesDirectory | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.outputDirectory} |
| 用户属性 | |
| 自 |
compilerArguments
应提供给 AOT 编译过程的参数。在命令行中,请确保将多个值用引号括起来。
compilerArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.aot.compilerArguments |
| 起始版本 |
excludeGroupIds
要排除的 groupId 名称的逗号分隔列表(精确匹配)。
excludeGroupIds | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.excludeGroupIds |
| 起始版本 | 1.1.0 |
excludes
要排除的构件定义集合。Exclude 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
excludes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.excludes |
| 起始版本 | 1.1.0 |
generatedClasses
包含生成的测试类的目录。
generatedClasses | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/main/classes |
| 用户属性 | |
| 起始版本 |
generatedResources
包含生成的测试资源的目录。
generatedResources | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/test/resources |
| 用户属性 | |
| 自 |
generatedSources
包含生成源代码的目录。
generatedSources | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/test/sources |
| 用户属性 | |
| 起始版本 |
generatedTestClasses
包含生成的测试类的目录。
generatedTestClasses | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.directory}/spring-aot/test/classes |
| 用户属性 | |
| 自 |
includes
要包含的构件定义集合。Include 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
includes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.includes |
| 起始版本 | 1.2.0 |
jvmArguments
应与 AOT 进程关联的 JVM 参数。在命令行中,请确保将多个值用引号括起来。
jvmArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.aot.jvmArguments |
| 起始版本 |
skip
跳过执行。
skip | |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 用户属性 | spring-boot.aot.skip |
| 自 |
systemPropertyVariables
要传递给 AOT 进程的 JVM 系统属性列表。
systemPropertyVariables | |
|---|---|
| 类型 | java.util.Map |
| 默认值 | |
| 用户属性 | |
| 自 |
testClassesDirectory
包含应打包到归档文件中的类和资源文件的目录。
testClassesDirectory | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.testOutputDirectory} |
| 用户属性 | |
| 自 |