Advanced Native Images Topics
Nested Configuration Properties
春季预先引擎自动为配置属性创建反射提示。然而,不是内部类的嵌套配置属性,*must*使用 `@NestedConfigurationProperty`进行注释,否则它们将不会被检测到,并且不会被绑定。
其中 `Nested`为:
上面的示例为 `my.properties.name`和 `my.properties.nested.number`生成了配置属性。如果没有 `nested`字段上的 `@NestedConfigurationProperty`注释,那么 `my.properties.nested.number`属性在本地镜像中将不可绑定。
在使用构造函数绑定时,您必须使用 `@NestedConfigurationProperty`注释字段:
在使用记录时,您必须使用 `@NestedConfigurationProperty`注释参数:
在使用 Kotlin 时,您需要使用 `@NestedConfigurationProperty`注释数据类的参数:
请在所有情况下使用公共获取器和设置器,否则这些属性将不可绑定。 |
Converting a Spring Boot Executable Jar
只要 jar 中包含 AOT 生成的资产,就可以将 Spring Boot executable jar 转换为本机映像。这可能在许多情况下很有用,包括:
-
您可以保留常规 JVM 进程并将 JVM 应用程序转换为 CI/CD 平台上的本机映像。
-
如
native-image
does not support cross-compilation 所述,您可以保留一个操作系统中立的部署工件,之后将其转换为不同的操作系统架构。
可以使用 Cloud Native Buildpacks 或 GraalVM 附带的 native-image
工具将 Spring Boot 可执行 jar 转换为本机映像。
可执行 jar 必须包括生成的类和 JSON 提示文件等 AOT 生成的资产。 |
Using Buildpacks
Spring Boot 应用程序通常通过 Maven (mvn spring-boot:build-image
) 或 Gradle (gradle bootBuildImage
) 集成使用 Cloud Native Buildpacks。但是,您还可以使用 pack
将经过 AOT 处理的 Spring Boot 可执行 jar 转换为本机容器映像。
首先,请确保有 Docker 守护程序(有关详细信息,请参见 Get Docker)。如果您使用 Linux,请参见 Configure it to allow non-root user。
您还需要按照 the installation guide on buildpacks.io 安装 pack
。
假设正在 target
目录中构建的经过 AOT 处理的 Spring Boot 可执行 jar 是 myproject-0.0.1-SNAPSHOT.jar
,请运行:
$ pack build --builder paketobuildpacks/builder-jammy-tiny \
--path target/myproject-0.0.1-SNAPSHOT.jar \
--env 'BP_NATIVE_IMAGE=true' \
my-application:0.0.1-SNAPSHOT
您无需本地安装 GraalVM 即可生成图像。 |
一旦 pack
完成,您就可以使用 docker run
启动应用程序:
$ docker run --rm -p 8080:8080 docker.io/library/myproject:0.0.1-SNAPSHOT
Using GraalVM native-image
将经过 AOT 处理的 Spring Boot 可执行 jar 转换为本机可执行文件的另一种选择是使用 GraalVM native-image
工具。要使其正常工作,您的机器上需要有 GraalVM 发行版。您可以手动在 {url-download-liberica-nik}[Liberica Native Image Kit 页面] 上下载它,也可以使用如 SDKMAN! 之类的下载管理器下载它。
假设正在 target
目录中构建的经过 AOT 处理的 Spring Boot 可执行 jar 是 myproject-0.0.1-SNAPSHOT.jar
,请运行:
$ rm -rf target/native
$ mkdir -p target/native
$ cd target/native
$ jar -xvf ../myproject-0.0.1-SNAPSHOT.jar
$ native-image -H:Name=myproject @META-INF/native-image/argfile -cp .:BOOT-INF/classes:`find BOOT-INF/lib | tr '\n' ':'`
$ mv myproject ../
这些命令适用于 Linux 或 macOS 机器,但是您需要根据 Windows 对其进行调整。 |
|
native-image
-cp
标志不接受通配符。您需要确保列出所有 jar(上述命令使用 find
和 tr
完成此操作)。
Using the Tracing Agent
GraalVM 本机映像允许您在 JVM 上拦截反射、资源或代理使用情况,以生成相关提示。Spring 应该自动生成大部分这些提示,但可以快速使用跟踪代理识别缺失的条目。
在使用该代理为本机映像生成提示时,有一些方法:
-
直接启动应用程序并使用它。
-
运行应用程序测试来使用应用程序。
第一个选项当 Spring 不识别某个库或模式时,对于识别缺少的提示很有用。
第二个选项对于可重复设置听起来更有吸引力,但默认情况下,生成的提示将包括测试基础结构所需的任何内容。在应用程序实际运行时,其中一些将是不必要的。为了解决这个问题,该代理支持一个访问筛选器文件,它将导致某些数据从生成输出中排除。
Launch the Application Directly
使用以下命令启动带有本机映像跟踪代理的应用程序:
$ java -Dspring.aot.enabled=true \
-agentlib:native-image-agent=config-output-dir=/path/to/config-dir/ \
-jar target/myproject-0.0.1-SNAPSHOT.jar
现在,您可以运行您希望具有提示的代码路径,然后使用 ctrl-c
停止应用程序。
在应用程序关闭时,本机映像跟踪代理将提示文件写入到给定的配置输出目录。您可以手动检查这些文件,或将它们用作本机映像构建进程的输入。若要将它们用作输入,请将它们复制到 src/main/resources/META-INF/native-image/
目录。下次构建本机映像时,GraalVM 将考虑这些文件。
可在本机映像跟踪代理上设置更多高级选项,例如按调用类等过滤记录的提示。如需进一步了解,请参阅 {url-graal-docs-native-image}/metadata/AutomaticMetadataCollection[官方文档]。
Custom Hints
如果您需要为反射、资源、序列化、代理使用等提供您自己的提示,则可以使用 RuntimeHintsRegistrar
API。创建一个实现 RuntimeHintsRegistrar
接口的类,然后对提供的 RuntimeHints
实例进行适当的调用:
然后,您可以在任何 @Configuration
类(例如您带 @SpringBootApplication
注释的应用程序类)上使用 @ImportRuntimeHints
来激活这些提示。
如果您有需要绑定的类(主要在序列化或反序列化 JSON 时需要),您可以在任何 bean 上使用 {url-spring-framework-docs}/core/aot.html#aot.hints.register-reflection-for-binding[@RegisterReflectionForBinding
]。大部分提示都是自动推断的,例如在接受或返回 @RestController
方法的数据时。但在直接使用 WebClient
、RestClient
或 RestTemplate
时,您可能需要使用 @RegisterReflectionForBinding
。
Known Limitations
GraalVM 本机映像是一项不断发展的技术,并非所有库都提供支持。GraalVM 社区正在提供 reachability metadata 来帮助那些尚未发布自己的项目的项目。Spring 本身并不包含面向第三方库的提示,而是依赖于可达性元数据项目。
如果您在为 Spring Boot 应用程序生成本机映像时遇到问题,请查看 Spring Boot Wiki 的 {url-github-wiki}/Spring-Boot-with-GraalVM[Spring Boot with GraalVM] 页面。您也可以将问题提交到 GitHub 上的 spring-aot-smoke-tests 项目,该项目用于确认常见的应用程序类型按预期工作。
如果您发现某个库不适用于 GraalVM,请在 reachability metadata project 上提出问题。