预编译处理(Ahead-of-Time Processing)

Spring AOT 是一种在构建时分析你的应用并生成其优化版本的过程。 要在 native image 中运行 Spring ApplicationContext,这是必需的步骤。

关于 Spring Boot 对 GraalVM Native Images 的支持,请参阅 参考文档

Spring Boot Maven 插件提供了可用于对应用和测试代码执行 AOT 处理的目标(goal)。

处理应用程序

要配置你的应用以使用此功能,请为 process-aot 目标添加一个 execution,如下例所示:

<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 目标 共享许多属性。

使用 Native 配置文件(Profile)

如果你的项目以 spring-boot-starter-parent 作为 parent,可以使用 native 配置文件简化 native image 构建所需的步骤。

native 配置文件会进行如下配置:

  • 当 Spring Boot Maven 插件应用于项目时,执行 process-aot

  • 适当设置,使 build-image 生成 native image。

  • Native Build Tools Maven Plugin 提供合理默认值,具体包括:

    • 确保插件使用原始 classpath,而不是主 jar 文件(因其无法识别我们重新打包的 jar 格式)。

    • 校验合适的 GraalVM 版本是否可用。

    • 下载第三方 reachability metadata。

使用原始 classpath 意味着 native image 无法识别生成的 MANIFEST.MF。 如果你需要在 native image 中读取 manifest 内容(例如获取应用实现版本),请将 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>

单个项目可通过命令行触发 native image 生成,方式包括 Cloud Native BuildpacksNative Image Build Tools

对于多模块项目,可自定义 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>

完成上述配置后,你可以构建多模块项目,并在相关子模块中生成 native image,如下例所示:

$ mvn package -Pnative
“相关”子模块指的是代表 Spring Boot 应用的模块。 此类模块必须如上所述定义 Native Build Tools 和 Spring Boot 插件。

spring-boot:process-aot

org.springframework.boot:spring-boot-maven-plugin:3.5.0

Invoke the AOT engine on the application.

Required parameters

Name Type Default

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

Optional parameters

Name Type Default

arguments

String[]

compilerArguments

String

excludeGroupIds

String

excludes

List

includes

List

jvmArguments

String

mainClass

String

profiles

String[]

skip

boolean

false

systemPropertyVariables

Map

Parameter details

arguments

Application arguments that should be taken into account for AOT processing.

Name

arguments

Type

java.lang.String[]

Default value

User property

Since

classesDirectory

Directory containing the classes and resource files that should be packaged into the archive.

Name

classesDirectory

Type

java.io.File

Default value

${project.build.outputDirectory}

User property

Since

compilerArguments

Arguments that should be provided to the AOT compile process. On command line, make sure to wrap multiple values between quotes.

Name

compilerArguments

Type

java.lang.String

Default value

User property

spring-boot.aot.compilerArguments

Since

excludeGroupIds

Comma separated list of groupId names to exclude (exact match).

Name

excludeGroupIds

Type

java.lang.String

Default value

User property

spring-boot.excludeGroupIds

Since

1.1.0

excludes

Collection of artifact definitions to exclude. The Exclude element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

excludes

Type

java.util.List

Default value

User property

spring-boot.excludes

Since

1.1.0

generatedClasses

Directory containing the generated classes.

Name

generatedClasses

Type

java.io.File

Default value

${project.build.directory}/spring-aot/main/classes

User property

Since

generatedResources

Directory containing the generated resources.

Name

generatedResources

Type

java.io.File

Default value

${project.build.directory}/spring-aot/main/resources

User property

Since

generatedSources

Directory containing the generated sources.

Name

generatedSources

Type

java.io.File

Default value

${project.build.directory}/spring-aot/main/sources

User property

Since

includes

Collection of artifact definitions to include. The Include element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

includes

Type

java.util.List

Default value

User property

spring-boot.includes

Since

1.2.0

jvmArguments

JVM arguments that should be associated with the AOT process. On command line, make sure to wrap multiple values between quotes.

Name

jvmArguments

Type

java.lang.String

Default value

User property

spring-boot.aot.jvmArguments

Since

mainClass

Name of the main class to use as the source for the AOT process. If not specified the first compiled class found that contains a 'main' method will be used.

Name

mainClass

Type

java.lang.String

Default value

User property

spring-boot.aot.main-class

Since

profiles

Spring profiles to take into account for AOT processing.

Name

profiles

Type

java.lang.String[]

Default value

User property

Since

skip

Skip the execution.

Name

skip

Type

boolean

Default value

false

User property

spring-boot.aot.skip

Since

systemPropertyVariables

List of JVM system properties to pass to the AOT process.

Name

systemPropertyVariables

Type

java.util.Map

Default value

User property

Since

处理测试

AOT 引擎可应用于使用 Spring Test Context Framework 的 JUnit 5 测试。 这些测试会被 AOT 引擎处理,并在 native image 中执行。

生产代码 类似,spring-boot-starter-parent 定义了 nativeTest 配置文件,可简化在 native image 中执行测试所需的步骤。

nativeTest 配置文件会进行如下配置:

  • 当 Spring Boot Maven 插件应用于项目时,执行 process-test-aot

  • Native Build Tools Maven Plugin 应用于项目时,执行 test。 该执行定义了合理默认值,具体包括:

    • 确保插件使用原始 classpath,而不是主 jar 文件(因其无法识别我们重新打包的 jar 格式)。

    • 校验合适的 GraalVM 版本是否可用。

    • 下载第三方 reachability metadata。

要使用 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:3.5.0

Invoke the AOT engine on tests.

Required parameters

Name Type Default

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}

Optional parameters

Name Type Default

compilerArguments

String

excludeGroupIds

String

excludes

List

includes

List

jvmArguments

String

skip

boolean

false

systemPropertyVariables

Map

Parameter details

classesDirectory

Directory containing the classes and resource files that should be used to run the tests.

Name

classesDirectory

Type

java.io.File

Default value

${project.build.outputDirectory}

User property

Since

compilerArguments

Arguments that should be provided to the AOT compile process. On command line, make sure to wrap multiple values between quotes.

Name

compilerArguments

Type

java.lang.String

Default value

User property

spring-boot.aot.compilerArguments

Since

excludeGroupIds

Comma separated list of groupId names to exclude (exact match).

Name

excludeGroupIds

Type

java.lang.String

Default value

User property

spring-boot.excludeGroupIds

Since

1.1.0

excludes

Collection of artifact definitions to exclude. The Exclude element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

excludes

Type

java.util.List

Default value

User property

spring-boot.excludes

Since

1.1.0

generatedClasses

Directory containing the generated test classes.

Name

generatedClasses

Type

java.io.File

Default value

${project.build.directory}/spring-aot/main/classes

User property

Since

generatedResources

Directory containing the generated test resources.

Name

generatedResources

Type

java.io.File

Default value

${project.build.directory}/spring-aot/test/resources

User property

Since

generatedSources

Directory containing the generated sources.

Name

generatedSources

Type

java.io.File

Default value

${project.build.directory}/spring-aot/test/sources

User property

Since

generatedTestClasses

Directory containing the generated test classes.

Name

generatedTestClasses

Type

java.io.File

Default value

${project.build.directory}/spring-aot/test/classes

User property

Since

includes

Collection of artifact definitions to include. The Include element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

includes

Type

java.util.List

Default value

User property

spring-boot.includes

Since

1.2.0

jvmArguments

JVM arguments that should be associated with the AOT process. On command line, make sure to wrap multiple values between quotes.

Name

jvmArguments

Type

java.lang.String

Default value

User property

spring-boot.aot.jvmArguments

Since

skip

Skip the execution.

Name

skip

Type

boolean

Default value

false

User property

spring-boot.aot.skip

Since

systemPropertyVariables

List of JVM system properties to pass to the AOT process.

Name

systemPropertyVariables

Type

java.util.Map

Default value

User property

Since

testClassesDirectory

Directory containing the classes and resource files that should be packaged into the archive.

Name

testClassesDirectory

Type

java.io.File

Default value

${project.build.testOutputDirectory}

User property

Since