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

打印 上一主题 下一主题

主题 506|帖子 506|积分 1518

注:本文基于 newbeemall 项目升级Spring Boot3.0踩坑总结而来。
一. 编译报错,import javax.servlet.*; 不存在

这个报错主要是Spring Boot3.0已经为所有依赖项从 Java EE 迁移到 Jakarta EE API,导致 servlet 包名的修改,Spring团队如许做的原因,主要是避免 Oracle 的版权题目,解决办法很简朴,两步走:
1 添加 jakarta.servlet 依赖
  1. <dependency>
  2.     <groupId>jakarta.servlet</groupId>
  3.     <artifactId>jakarta.servlet-api</artifactId>
  4. </dependency>
复制代码

  • 修改项目内所有代码的导入依赖
  1. 修改前:
  2. import javax.servlet.*
  3. 修改后:
  4. import jakarta.servlet.*
复制代码
二. 附带的众多依赖包升级,导致的部分代码写法过期报警

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

  1. 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.
  2. 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.
复制代码
可以看出作者很知心,日记里已经给出了升级后的写法,修改如下:
  1. 修改前:
  2. <th:block th:include="admin/header :: header-fragment"/>
  3. 修改后:
  4. <th:block th:insert="~{admin/header :: header-fragment}"/>
复制代码
2.2 Thymeleaf升级到3.1.0.M2,后端使用 thymeleafViewResolver 手动渲染网页代码报错
  1. // 修改前 Spring Boot2.7:
  2. WebContext ctx = new (request, response,
  3.         request.getServletContext(), request.getLocale(), model.asMap());
  4. html = thymeleafViewResolver.getTemplateEngine().process("mall/seckill-list", ctx);
复制代码

上述代码中针对 WebContext 对象的创建报错,这里直接给出新版写法
  1. // 修改后 Spring Boot3.0:
  2. JakartaServletWebApplication jakartaServletWebApplication = JakartaServletWebApplication.buildApplication(request.getServletContext());
  3. WebContext ctx = new WebContext(jakartaServletWebApplication.buildExchange(request, response), request.getLocale(), model.asMap());
  4. 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-发布阐明 中
  这里给出两个解决方案:

  • 等候第三方库适配 Spring Boot 3.0
  • 按照 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官方堆栈,这里我就不得不动用我的小聪明,给出解决方案:


  • 手动将原有的 MybatisSqlSessionFactoryBean 类代码复制到一个我们自己代码目录下新建的 MybatisSqlSessionFactoryBean 类,去掉 NestedIOException 依赖
  • 数据源自动配置代码修改
  1. @Slf4j
  2. @EnableConfigurationProperties(MybatisPlusProperties.class)
  3. @EnableTransactionManagement
  4. @EnableAspectJAutoProxy
  5. @Configuration
  6. @MapperScan(basePackages = "ltd.newbee.mall.core.dao", sqlSessionFactoryRef = "masterSqlSessionFactory")
  7. public class HikariCpConfig {
  8.     @Bean
  9.     public MybatisPlusInterceptor mybatisPlusInterceptor() {
  10.         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  11.         interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  12.         return interceptor;
  13.     }
  14.     @Bean(name = "masterDataSource")
  15.     @ConfigurationProperties(prefix = "spring.datasource.master")
  16.     public DataSource masterDataSource() {
  17.         return new HikariDataSource();
  18.     }
  19.     /**
  20.      * @param datasource 数据源
  21.      * @return SqlSessionFactory
  22.      * @Primary 默认SqlSessionFactory
  23.      */
  24.     @Bean(name = "masterSqlSessionFactory")
  25.     public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource datasource,
  26.                                                      Interceptor interceptor,
  27.                                                      MybatisPlusProperties properties) throws Exception {
  28.         MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
  29.         bean.setDataSource(datasource);
  30.         // 兼容mybatis plus的自动配置写法
  31.         bean.setMapperLocations(properties.resolveMapperLocations());
  32.         if (properties.getConfigurationProperties() != null) {
  33.             bean.setConfigurationProperties(properties.getConfigurationProperties());
  34.         }
  35.         if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
  36.             bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
  37.         }
  38.         bean.setPlugins(interceptor);
  39.         GlobalConfig globalConfig = properties.getGlobalConfig();
  40.         bean.setGlobalConfig(globalConfig);
  41.         log.info("------------------------------------------masterDataSource 配置成功");
  42.         return bean.getObject();
  43.     }
  44.     @Bean("masterSessionTemplate")
  45.     public SqlSessionTemplate masterSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  46.         return new SqlSessionTemplate(sqlSessionFactory);
  47.     }
  48. }
复制代码
到这里,项目就可以或许正常跑起来了
总结

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表