背景

我们不再具体介绍GraalVM,直接介绍改造过程。
项目使用Spring Boot 2.0.8,使用了Eureka、Mybatis、TKMyBatis、MySQL

结论:Spring Boot 官方在3.x版本对于GraalVM做了很多的工作,兼容性较好。但是一旦引入了MyBatis以及TKMyBatis 后,各种问题。

最终改造后的版本:

组件 版本
GraalVM 17
Spring boot 3.2
Spring Cloud 2023
Mybatis 3.5.19
mybatis-spring-boot-autoconfigure 3.0.5
mybatis-spring 3.0.5

1、升级 Spring Boot

即使Spring官方提供了 Native 工具用于适配Spring Boot 2.x的版本,但是实际上版本对应关系等问题还是比较多的。因此项目首先升级到了Spring Boot 3.2,选择了GraalVM 17。

问题一:
项目从Spring Boot 2.x升级到Spring Boot3.x后,以及使用GraalVM 17后,要关注一些拦截器、javax的类替换,在新的版本中这些组件都有相应的变换。

问题二:
需要升级Mybatis、Mybatis Spring相应版本,兼容Spring Boot 3.x。
Mybatis 3.5.19
mybatis-spring-boot-autoconfigure 3.0.5
mybatis-spring 3.0.5

问题三:
升级Spring Cloud至2023,兼容Spring Boot 3.x。由于项目只用到了Eureka,升级相对简单。
解决上述问题后,在pom里添加GraalVM插件依赖.

<plugin>
  <groupId>org.graalvm.buildtools</groupId>
  <artifactId>native-maven-plugin</artifactId>
</plugin>

在application配置文件里,关闭refresh功能

spring:
  cloud:
    refresh:
      enabled: false

2、Mybatis适配

上述升级完成后,使用mvn clean package -Pnative还是会报错的。

问题一:
tkmyabtis适配问题,AOT会提示以下报错。

failed to generate code for applicationservletenvironment

最后项目不得不把tkmybatis的依赖移除,才不会有该报错。

问题二
重新AOT和编译为可执行文件后,运行会新的错误。报错类似以下内容

org.mybatis.spring.mapper.classpathmapperscanner case java.lang.NullPointerException

这时候需要做以下2个步骤:

  1. 复制网页内容 https://github.com/mybatis/spring-boot-starter/wiki/MyBatisNativeConfiguration.java 到自己的工程。
  2. 同时再参考 https://github.com/nieqiurong/mybatis-native-demo/commit/7c8977a 调整类里的以下内容。
    在这里插入图片描述

如果步骤二没做,项目里需要注入Mapper的地方,会报错

org mybatis spring mapper mapperfactorybean required a bean of type java.lang.class that could not be found

问题三:
重新AOT和编译为可执行文件后,运行会新的错误。

IllegalArgumentException: property sqlsessionfactory or sqlsessiontemplate are required

如果工程中使用到了@MapperScanner注解,需要指定sqlSessionTemplateRef

@MapperScan(basePackages = "com.example.mybatisnativesample.mapper", sqlSessionTemplateRef = "sqlSessionTemplate")

问题四:

重新AOT和编译为可执行文件后,运行会新的错误。意思为接口无法绑定XML。

invalid bound statement (not found) com.xxxx.xxx

这个问题大概原因是没有把xml扫描加载成功。虽然我们在application配置里配置了xmlLocation和mapper-locations,但是在GraalVM下是无效的。官方有一个方法 https://github.com/mybatis/spring-native/blob/master/docs/src/site/zh/markdown/index.md#%E4%BD%BF%E7%94%A8-mybatisresourcesscan 使用@MyBatisResourcesScan注解。

该注解需要依赖mybatis-spring-native-core,使用myabtis的Maven仓库,参考 https://github.com/mybatis/spring-native?tab=readme-ov-file#how-to-install-on-your-application

由于我的项目在内网,所以我最后把xml的SQL都改造成了Mybatis 注解模式使用。
通过上述的改造,项目成功使用GraalVM 17编译打包,并能稳定运行。

Logo

惟楚有才,于斯为盛。欢迎来到长沙!!! 茶颜悦色、臭豆腐、CSDN和你一个都不能少~

更多推荐