开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
书接上文再 Spring Boot3.0升级,踩坑之旅,附解决方案 第一篇中我们介绍了大部分 Spring Boot3.0
升级所带来的破坏性修改,这篇文章将介绍剩下的修改部分,并针对Jdk17升级带来的优化写法进行案例展示。
本文基于 newbeemall 项目升级Spring Boot3.0踩坑总结而来
一。Jdk8中内置的JavaScript引擎 nashorn
被移除,导致验证码使用报错Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
项目中使用了 com.github.whvcse包的easy-captcha
验证码依赖,升级至Jdk17后,验证码接口报错:Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
,错误原因很明显脚本引擎执行脚本语句报错,因为执行引擎为空。查询相关资料Jdk8自带的JavaScript引擎 nashorn
再升级到Jdk9后就被移除了,从而导致报错
解决办法:添加JavaScript引擎 nashorn
依赖
一。Jdk8中内置的JavaScript引擎 nashorn 被移除,导致验证码使用报错Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null 项目中使用了 com.github.whvcse包的easy-captcha 验证码依赖,升级至Jdk17后,验证码接口报错:Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null,错误原因很明显脚本引擎执行脚本语句报错,因为执行引擎为空。查询相关资料Jdk8自带的JavaScript引擎 nashorn 再升级到Jdk9后就被移除了,从而导致报错 解决办法:添加JavaScript引擎 nashorn依赖 作者:waynaqua 链接:https://juejin.cn/post/7181019431558971451 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二. Spring data redis
配置前缀被修改
在 Spring Boot2.0
中 redis的配置前缀为 spring.redis
但是在最新 Spring Boot3.0
中redis的配置前缀被修改为 spring.data.redis
,导致老项目中redis配置写法需要修改,如下图
这里我们猜测一波,Spring
对redis配置的破坏性修改可能是为了统一 Spring data
配置把。
解决办法,修改redis配置前缀为 spring.data.redis
三. 升级Jdk17的优化一些写法
3.1 文本块语法。再很多其他语言中早就支持的文本块写法,现在在Jdk17中也可以通过 """
语法使用啦,如下,针对一段 lua
脚本代码,我们再也不用通过字符串拼接了
private String buildLuaScript() { return "local c" + "\nc = redis.call('get',KEYS[1])" + "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + "\nreturn c;" + "\nend" + "\nc = redis.call('incr',KEYS[1])" + "\nif tonumber(c) == 1 then" + "\nredis.call('expire',KEYS[1],ARGV[2])" + "\nend" + "\nreturn c;"; }
文本块写法,代码可读性提高了一个档次
private String buildLuaScript() { return """ local c c = redis.call('get',KEYS[1]) if c and tonumber(c) > tonumber(ARGV[1]) then return c; end c = redis.call('incr',KEYS[1]) if tonumber(c) == 1 then redis.call('expire',KEYS[1],ARGV[2]) end return c;"""; }
3.2 instanceof
模式匹配
Jdk17中针对 instanceof
关键字支持模式变量定义,可以减少不必要的强制转换逻辑,如下
java
复制代码
if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); if (annotation != null) { if (this.isRepeatSubmit(request)) { R error = R.error("不允许重复提交,请稍后再试"); ServletUtil.renderString(response, JSON.toJSONString(error)); return false; } } }
使用模式变量,可以消除代码中不必要的类型转换
if (handler instanceof HandlerMethod handlerMethod) { Method method = handlerMethod.getMethod(); RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); if (annotation != null) { if (this.isRepeatSubmit(request)) { R error = R.error("不允许重复提交,请稍后再试"); ServletUtil.renderString(response, JSON.toJSONString(error)); return false; } } }
3.3 switch
表达式扩展
升级到Jdk17后支持 switch
表达式扩展写法,优化前的写法
public static String getExtension(String prefix) { switch (prefix) { case IMAGE_PNG: return "png"; case IMAGE_JPG: return "jpg"; case IMAGE_JPEG: return "jpeg"; case IMAGE_BMP: return "bmp"; case IMAGE_GIF: return "gif"; default: return ""; } }
使用 switch
表达式扩展
public static String getExtension(String prefix) { return switch (prefix) { case IMAGE_PNG -> "png"; case IMAGE_JPG -> "jpg"; case IMAGE_JPEG -> "jpeg"; case IMAGE_BMP -> "bmp"; case IMAGE_GIF -> "gif"; default -> ""; }; }
总结
本文介绍了Spring Boot 3.0
升级带来了破坏性更改第二部分介绍,也展示了一些新版Jdk的优化写法,希望更多的朋友能够尝试升级到最新 Spring Boot 3.0
,紧跟时代潮流