赞
踩
本文基于 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>
修改前:
import javax.servlet.*
修改后:
import jakarta.servlet.*
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}"/>
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-发布说明 中
这里给出两个解决方案:
Spring Boot
3.0Spring Boot
3.0要求,在项目resources
下新建 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件,手动将第三方库的 spring.factories
加到 imports
中,这样可以手动修复第三方库 spring boot starter
依赖失效问题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中这个类还存在,给出类说明截图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8Zl1xum-1670140387552)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/43102c773a56425fbe88118555a950ad~tplv-k3u1fbpfcp-watermark.image?)]
这个类在2.7中已经被标记为废弃,建议替换为 IOException
, 而 Mybatis plus
3.5.2中还在使用。这里给出问题截图 MybatisSqlSessionFactoryBean
这个类还在使用 NestedIOException
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1cw1A1q0-1670140387554)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/383b78a7ffa6405fb5080cab0d407a24~tplv-k3u1fbpfcp-watermark.image?)]
查看 Mybatis plus
官方issue也已经有人提到了这个问题,官方的说法是 mybatis-plus-spring-boot-starter
还在验证尚未推送maven官方仓库,这里我就不得不动用我的小聪明,给出解决方案:
MybatisSqlSessionFactoryBean
类代码复制到一个我们自己代码目录下新建的 MybatisSqlSessionFactoryBean
类,去掉 NestedIOException
依赖@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 带来的新变化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。