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打包。

如果是本地使用IDEA打包,可以使用右侧maven图标-》主引用模块下 -》Plugins -》spring-boot -》spring-boot:process-aot
注:这个工程有使用到BOM(版本清单),我自己在测试的时候,是对这个BOM模块install到本地仓库