spring aot分析

发布时间 2023-10-29 17:15:36作者: Lht1

native-image

graalvm支持使用native-image工具来生成二进制可执行文件。

对于运行时反射需要使用agent在运行时收集元信息,即META-INF/native-image/xxx/*.json文件。

通过agent收集元数据的文章:https://www.graalvm.org/reference-manual/native-image/guides/configure-with-tracing-agent/

export JAVA_TOOP_OPTIONS="-agentlib:native-image-agent=config-output-dir=/path/to/META-INF/native-image/xxx"

也可以实现org.graalvm.nativeimage.hosted.Feature接口,并设置META-INF/native-image/xxx/native-image.properties中的参数。

native-image.properties文件的文章:https://www.graalvm.org/22.1/reference-manual/native-image/BuildConfiguration/

Spring aot的实现:

native-image.properties格式:

Args = xxx      // native-image参数
JavaArgs = xxx  // jvm参数
ImageName = xxx // 镜像名称, 如果用户没指定则使用此的镜像名称

spring中ContextAotProcessor类生成native-image.properties的方法:

image-20231029155800405

image-20231029153421043

image-20231029153707040

常见的native-image参数:

参数 解释
--features a comma-separated list of fully qualified Feature implementation classes
--initialize-at-build-time a comma-separated list of packages and classes (and implicitly all of their superclasses) that are initialized during image generation. An empty string designates all packages
--initialize-at-run-time a comma-separated list of packages and classes (and implicitly all of their subclasses) that must be initialized at runtime and not during image building. An empty string is currently not supported
--install-exit-handlers provide java.lang.Terminator exit handlers
--no-fallback build stand-alone image or report failure
-H:Class Class containing the default entry point method. Optional if --shared is used

native-image会自动读取环境变量$NATIVE_IMAGE_CONFIG_FILE的properties文件中的NativeImageArgs作为native-image参数。

例如:这个export就设置默认读取的配置文件在$HOME/.native-image/default.properties下。

export NATIVE_IMAGE_CONFIG_FILE=$HOME/.native-image/default.properties

文件格式:

NativeImageArgs = --configurations-path /home/user/custom-image-configs \
                  -O1

native-image可以通过native-image --expert-options-all命令来查看所有所有隐藏配置。

spring aot实现

spring aot有三种方式来设置反射元数据。

  • @ImportRuntimeHints:通过注解导入一个RuntimeHintsRegistrar接口的实现类。

    image-20231029164038870

  • RuntimeHintsRegistrar接口:实现RuntimeHintsRegistrar接口并导入容器。

  • Reflective注解:默认通过SimpleReflectiveProcessor类进行处理,支持注解在类、构造器、属性、方法上。

    image-20231029164327777

这三种方式都是会把类型信息写入DefaultGenerationContextRuntimeHints中。

然后RuntimeHints里的所有反射信息会通过FileNativeConfigurationWriter类分别写入文件系统中的META-INF/native-image/groupId/artifactId/xxx.json文件,json文件的格式写入方式是通过BasicJsonWriter类来实现的。

通过把ApplicationClass写入到META-INF/native-image/groupId/artifactId/native-image.properties文件

格式如下:

Args = -H:Class=xxx,yyy \
--report-unsupported-elements-at-runtime \
--no-fallback \
--install-exit-handlers

image-20231029164917329

image-20231029164648186