简谈Spring Boot3.0升级后的踩坑之旅,另附解决方案!

news2024/10/6 16:19:45

注:本文基于 newbeemall 项目升级Spring Boot3.0踩坑总结而来。

一. 编译报错,import javax.servlet.*; 不存在

这个报错主要是Spring Boot3.0已经为所有依赖项从 Java EE 迁移到 Jakarta EE API,导致 servlet 包名的修改,Spring团队这样做的原因,主要是避免 Oracle 的版权问题,解决办法很简单,两步走:

1 添加 jakarta.servlet 依赖

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
</dependency>
  1. 修改项目内所有代码的导入依赖

修改前:
import javax.servlet.*
修改后:
import jakarta.servlet.*

二. 附带的众多依赖包升级,导致的部分代码写法过期报警

2.1 Thymeleaf升级到3.1.0.M2,日志打印的报警

14:40:39.936 [http-nio-84-exec-15] WARN  o.t.s.p.StandardIncludeTagProcessor - [doProcess,67] - [THYMELEAF][http-nio-84-exec-15][admin/goods/goods] Deprecated attribute {th:include,data-th-include} found in template admin/goods/goods, line 4, col 15. Please use {th:insert,data-th-insert} instead, this deprecated attribute will be removed in future versions of Thymeleaf.
14:40:39.936 [http-nio-84-exec-15] WARN  o.t.s.p.AbstractStandardFragmentInsertionTagProcessor - [computeFragment,385] - [THYMELEAF][http-nio-84-exec-15][admin/goods/goods] Deprecated unwrapped fragment expression "admin/header :: header-fragment" found in template admin/goods/goods, line 4, col 15. Please use the complete syntax of fragment expressions instead ("~{admin/header :: header-fragment}"). The old, unwrapped syntax for fragment expressions will be removed in future versions of Thymeleaf.

可以看出作者很贴心,日志里已经给出了升级后的写法,修改如下:

修改前:
<th:block th:include="admin/header :: header-fragment"/>
修改后:
<th:block th:insert="~{admin/header :: header-fragment}"/>

2.2 Thymeleaf升级到3.1.0.M2,后端使用 thymeleafViewResolver 手动渲染网页代码报错

// 修改前 Spring Boot2.7:
WebContext ctx = new (request, response,
        request.getServletContext(), request.getLocale(), model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("mall/seckill-list", ctx);

上述代码中针对 WebContext 对象的创建报错,这里直接给出新版写法

// 修改后 Spring Boot3.0:
JakartaServletWebApplication jakartaServletWebApplication = JakartaServletWebApplication.buildApplication(request.getServletContext());
WebContext ctx = new WebContext(jakartaServletWebApplication.buildExchange(request, response), request.getLocale(), model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("mall/seckill-list", ctx);

三. 大量第三方库关于 Spring Boot 的 starter 依赖失效,导致项目启动报错

博主升级到3.0后,发现启动时,Druid 数据源开始报错,找不到数据源配置,便怀疑跟 Spring boot 3.0 更新有关

这里直接给出原因:Spring Boot 3.0 中自动配置注册的 spring.factories 写法已废弃,改为了 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 写法,导致大量第三方 starter 依赖失效

在吐槽一下,这么重要的更改在Spring官方的 Spring-Boot-3.0-发布说明 中竟然没有,被放在了 Spring-Boot-3.0.0-M5-发布说明 中

这里给出两个解决方案:

  1. 等待第三方库适配 Spring Boot 3.0

  2. 按照 Spring Boot 3.0要求,在项目resources 下新建 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,手动将第三方库的 spring.factories 加到 imports 中,这样可以手动修复第三方库 spring boot starter 依赖失效问题

四. Mybatis Plus 依赖问题

Mybatis plus 最新版本还是3.5.2,其依赖的 mybatis-spring 版本是2.2.2(mybatis-spring 已经发布了3.0.0版本适配 Spring Boot 3.0),这会导致项目中的sql查询直接报错,这里主要是因 Spring Boot 3.0中删除 NestedIOException 这个类,在 Spring boot 2.7中这个类还存在,给出类说明截图

​这个类在2.7中已经被标记为废弃,建议替换为 IOException, 而 Mybatis plus 3.5.2中还在使用。这里给出问题截图 MybatisSqlSessionFactoryBean 这个类还在使用 NestedIOException

​查看 Mybatis plus 官方issue也已经有人提到了这个问题,官方的说法是 mybatis-plus-spring-boot-starter 还在验证尚未推送maven官方仓库,这里我就不得不动用我的小聪明,给出解决方案:

  1. 手动将原有的 MybatisSqlSessionFactoryBean 类代码复制到一个我们自己代码目录下新建的 MybatisSqlSessionFactoryBean 类,去掉 NestedIOException 依赖

  2. 数据源自动配置代码修改

@Slf4j
@EnableConfigurationProperties(MybatisPlusProperties.class)
@EnableTransactionManagement
@EnableAspectJAutoProxy
@Configuration
@MapperScan(basePackages = "ltd.newbee.mall.core.dao", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class HikariCpConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }


    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return new HikariDataSource();
    }

    /**
     * @param datasource 数据源
     * @return SqlSessionFactory
     * @Primary 默认SqlSessionFactory
     */
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource datasource,
                                                     Interceptor interceptor,
                                                     MybatisPlusProperties properties) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(datasource);
        // 兼容mybatis plus的自动配置写法
        bean.setMapperLocations(properties.resolveMapperLocations());
        if (properties.getConfigurationProperties() != null) {
            bean.setConfigurationProperties(properties.getConfigurationProperties());
        }
        if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
            bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        }
        bean.setPlugins(interceptor);
        GlobalConfig globalConfig = properties.getGlobalConfig();
        bean.setGlobalConfig(globalConfig);
        log.info("------------------------------------------masterDataSource 配置成功");
        return bean.getObject();
    }

    @Bean("masterSessionTemplate")
    public SqlSessionTemplate masterSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

到这里,项目就能够正常跑起来了

总结

Spring Boot 3.0 升级带来了很多破坏性更改,把众多依赖升级到了最新,算是解决了一部分历史问题,也为了云原型需求,逐步适配 graalvm ,不管怎么样作为技术开发者,希望有更多的开发者来尝试 Spring Boot 3.0 带来的新变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66480.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

写了30000字 用 shell 脚本做自动化测试实战项目(全面、完整)

前言 项目中有一个功能&#xff0c;需要监控本地文件系统的变更&#xff0c;例如文件的增、删、改名、文件数据变动等等。之前只在 windows 上有实现&#xff0c;采用的是 iocp ReadDirectoryChanges 方案&#xff0c;现在随着整个应用移植到 mac 上&#xff0c;需要对这一部…

大数据智能交通未来会是怎样的交通状况?

大数据智能交通未来会是怎样的交通状况&#xff1f;智能交通也是智慧城市的一个重要组成部分将会改变我们的交通&#xff0c;交通少不了大数据的处理&#xff0c;人工智能自动驾驶离不开大数据的支撑。 实现智能交通需要高效地从海量数据中分析、挖掘所需的信息和规律&#xf…

缺少微信小程序测试经验?这篇文章带你从0开始

微信小程序已经越来越普遍&#xff0c;但目前接触小程序的项目相对较少&#xff0c;对小程序的特性也不了解&#xff0c;缺少小程序测试实战经验。 本文主要通过对微信小程序特性和测试点进行总结&#xff0c;储备测试知识&#xff0c;提高测试效率。 小程序发布审核 发布前…

Linux jprobe的使用和原理

文章目录前言一、demo1.1 demo演示1.2 struct jprobe二、jprobe 原理2.1 原理简介1.2 原理详解三、源码解析3.1 struct jprobe3.2 register_jprobe3.3 setjmp_pre_handler3.4 jprobe_return3.5 longjmp_break_handler四、Deprecated Features五、使用 perf-probe 获取函数参数总…

CentOS7一键安装OpenStack

环境 CentOS 7 CPU核心数&#xff1a;2x2 RAM&#xff1a;8G DISK&#xff1a;60G 问题说明 在安装openstack过程中&#xff0c;一直卡在下面过程&#xff1a; Testing if puppet apply is finished: 192.168.100.132_controller.pp [ | ]等待一会儿之后会报各种不同的错误…

crontab 实现秒级定时任务的执行(学习笔记)

crontab 实现秒级定时任务的执行 传统暴力法 crontab -e ***** /usr/bin/curl 地址 ***** sleep 10; /usr/bin/curl 地址 ***** sleep 20; /usr/bin/curl 地址地址 ***** sleep 30; /usr/bin/curl 地址 ***** sleep 40; /usr/bin/curl 地址 ***** sleep 50; /usr/bin/cu…

进程和计划任务管理

查看进程信息 ps ps命令 查看静态的进程统计信息 ps -elf 查看进程信息 top top命令 查看动态的进程排名信息 top 查看进程信息 pgrep pgrep命令 根据特定条件查询进程 PID 信息 pgrep -l “log” pgrep -l -U teacher -t tty1 查看进程信息 pstree pstree命令 以树…

面试害怕考到JVM? 看这一篇就够了~

目录 前言 一、JVM内存划分 二、类加载 2.1、类加载是在干什么&#xff1f; 2.2、类加载的过程 2.3、何时触发类加载&#xff1f; 2.4、双亲委派模型&#xff08;重点考察&#xff09; 2.4.1、什么是双亲委派模型&#xff1f; 2.4.2、涉及到的类加载器 2.4.3、详细过…

【树莓派】raspberry pi控制超声波测距

目录一、超声波1、模块介绍2、工作原理二、gettimeofday函数三、树莓派控制超声波测距一、超声波 1、模块介绍 简介&#xff1a;   超声波传感器模块上面通常有两个超声波元器件&#xff0c;一个用于发射&#xff0c;一个用于接收。 硬件: 电路板上有4个引脚&#xff1a; …

测试面试被问“期望薪资多少”,不要傻傻直接报价,高情商都这样说

对于软件测试从业者而言&#xff0c;面试很重要&#xff0c;因为那是拿到薪资报酬丰厚程度的关键&#xff0c;你的理论及实操经验确实都很棒&#xff0c;那就尽量别让自己的面试表现拖自己的后腿&#xff0c;否则大概率会让你的薪水大打折扣。 你在面试中是否也遇到很多次以下…

38寻找二叉树的最近公共祖先39序列化和反序列化

38.寻找二叉树的最近公共祖先 这题和上一题的区别在于这不是二叉搜索树&#xff0c;无法根据值的大小来判断节点的位置&#xff0c;于是需要遍历 法1 递归写法 递归在左右子树寻找o1和o2 import java.util.*;/** public class TreeNode {* int val 0;* TreeNode left …

12月编程语言排行榜公布啦~

2022年迎来了最后一个月&#xff0c;我们可以看到&#xff0c;在这一年中编程语言起起伏伏&#xff0c;有的语言始终炙手可热&#xff0c;而有的语言却逐渐“没落”...... 日前&#xff0c;全球知名TIOBE编程语言社区发布了12月编程语言排行榜&#xff0c;有哪些新变化&#x…

Test Squence测试过程中如何按照特定条件暂停或者停止仿真

在Simulink模型做Test Squence测试时&#xff0c;工程师有时候希望测试用例能按照自己期望的条件来停止或暂停仿真&#xff0c;这个期望的特定条件&#xff0c;可以是时间达到&#xff0c;也可以是任何能达到的特定状态。 具体实现方法如下&#xff1a; 1、在Test Harness测试…

公司 CTO:高性能开发,你不会 Netty,怎么好意思拿 20K?

主管&#xff1a;这个版块用 Netty 框架就可以了呀&#xff0c;不会吗&#xff1f; &#xff08;此时&#xff0c;公司 CTO 路过&#xff09; 某程序员&#xff1a;这个我真不会... 主管&#xff1a;好了好了&#xff0c;那这一块我交给别人去做&#xff0c;这个也不难啊&am…

代码随想录刷题记录day36 整数拆分+不同的二叉搜索树

代码随想录刷题记录day36 整数拆分不同的二叉搜索树 参考&#xff1a;代码随想录 343. 整数拆分 思想 一个数可以被拆分成2个数或者3个及以上的数。 dp[i]表示拆分i以后&#xff0c;得到的最大的乘积 拆分成两个数 j和i-j,拆分成三个数及以上 j 和dp[i-j]&#xff0c;dp[i…

面试10分钟就完事了,问的实在是太...

干了两年外包&#xff0c;本来想出来正儿八经找个互联网公司上班&#xff0c;没想到算法死在另一家厂子。 自从加入这家外包公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到11月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资…

【矩阵乘法】C++实现外部矩阵乘法

问题描述 ​ 使用文件和内存模拟系统缓存&#xff0c;并利用矩阵乘法验证实际和理论情况。 算法思想 设计一个Matrix类&#xff0c;其中Matrix是存在磁盘中的一个二进制文件&#xff0c;类通过保存的矩阵属性来读取磁盘。前八个字节为两个int32&#xff0c;保存矩阵的行列数…

Linux||报错:vboxuser is not in the sudoers file. This incident will be reported.

一、问题描述 打算在Ubuntu虚拟机上部署SonarQube时&#xff0c;为避免各种不必要的奇怪问题&#xff0c;预先使用sudo命令修改系统参数。 命令如下&#xff1a;sudo sysctl -w vm.max_map_count262144 报错如下&#xff1a;vboxuser is not in the sudoers file. This inciden…

制造业企业库存管理的现状与解决措施

在竞争激烈的现代经济时代&#xff0c;制造行业面临着巨大的挑战和压力&#xff0c;必须与时俱进&#xff0c;适应市场的各种变化才能生存并保持活力。随着经营模式的变化与产品数量的增加&#xff0c;对产品库存管理也提出更大的挑战。库存管理是指与库存相关的计划和控制活动…

数据库设计 Relational Language

除了最为常用的SQL语句之外&#xff0c;还存在着几种不常用的数据库语言&#xff0c;这里简单介绍&#xff0c;了解即可。 Relational Algebra(RA) 一种程序性语言&#xff0c;可以与SQL对应着转换&#xff0c;语法即转换规则如下&#xff1a; σ&#xff1a;与WHERE对应&am…