0%

springboot3的aot实践

springboot3的aot实践

AOT 如何进行优化

AOT(Ahead-Of-Time)优化是从Spring Framework 6开始引入的一个新特性,用于提升应用的启动性能和运行时效率。

可以简单理解为 :在编译阶段就把以往一些运行时的数据编译成静态代码,减少运行时开销,从而加快启动速度并降低内存使用。

比如核心功能有:

  • Bean 定义预解析:编译期解析 @Configuration 类、@Bean 方法,生成静态化的 Bean 定义元数据,避免运行时扫描。
  • 条件注解预处理:提前评估 @Conditional 条件是否生效,直接生成符合条件的配置,减少运行时判断。
  • 反射元数据生成:自动识别需要反射访问的类 / 方法,生成 reflect-config.json 等文件,供 GraalVM 原生编译使用。(当需要将引用编译为原生镜像时,AOT与GraalVM深度绑定,但若不需要编译为原生镜像,可以不使用GraalVM,仅仅使用AOT也可能有一定启动时间的提升)
  • 资源访问优化:提前收集应用所需的资源文件(如 application.properties),生成资源索引,避免运行时遍历目录。

实践

我在实践的时候不是新建一个空白工程,是直接使用gitee的ruoyi-flex的https://gitee.com/dataprince/ruoyi-flex

这个工程已经是springboot3的版本,它的配置上没有使用aot相关配置,或者说部分配置没有配置为aot编译可运行状态。

1.顶层POM里要声明说用的打包插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.verison}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<annotationProcessorPaths>
<path>
<groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
<version>${therapi-runtime-javadoc.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot.version}</version>
</path>
<path>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-processor</artifactId>
<version>${mapstruct-plus.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${mapstruct-plus.lombok.version}</version>
</path>
<path>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<version>${mybatis-flex.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugins>
<build>

2.主引用需要使用到spring-boot-maven-plugin打包插件(这个process-aot可以不配,通过使用mvn命令启动aot),AOT主要是作用在主应用上,所以在主应用打包为AOT前,其他子模块都需要打包完成(普通jar包)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<classifier>exec</classifier>
</configuration>
<executions>
<execution>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>

3.比如这个工程内还有一些其他模块(ruoyi-common,ruoyi-extra,ruoyi-modules),这些模块要能打成普通jar包,所以这里对这三个大模块的POM设置跳过spring-boot-maven-plugin打包(因为顶层的POM里设置了maven-compiler-plugin插件,所以当跳过spring-boot打包插件,那么打出的包就是普通jar包)

1
2
3
4
5
6
7
8
9
10
11
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>

4.打包命令

有的地方的教使用spring-boot:process-aot,但是我自己测试,命令会报错。

以下是我添加到jenkins中构建的命令,执行过程依次为:

清理 -》各个模块打包 -》打到本地仓库 -》使用springboot3的aot打包

mvn clean package install org.springframework.boot:spring-boot-maven-plugin:3.2.5:process-aot

最终打包出来的包里就会有很对静态编译的内容,并且模块代码都被打入结果包中:

左侧为不使用AOT打包,右侧为使用AOT打包。

image-20250912112459443.png

如果是本地使用IDEA打包,可以使用右侧maven图标-》主引用模块下 -》Plugins -》spring-boot -》spring-boot:process-aot

注:这个工程有使用到BOM(版本清单),我自己在测试的时候,是对这个BOM模块install到本地仓库

-------------本文结束感谢您的阅读-------------