Springboot项目升级2.2.x升至2.7.x

2023-09-19 01:56:04

依赖管理

spring-boot-starter-parent 升级为2.7.1

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
<!--        升级为2.7.x的版本-->
    <version>2.7.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

兼容老的配置文件格式,spring提供了专门的依赖进行兼容,但是建议还是在升级能成功运行之后进行配置的同步修改

<!--        升级2.7后支持yml环境变量名兼容-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>

如果使用了bootstrap.yml文件,升级之后默认是不会使用bootstrap.yml了,所以可能会导致启动之后配置没有生效,需要引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.0.4</version>
</dependency>

配置修改

2.7.x不会处理循环依赖问题,需要手动配置修改application.yml添加配置spring.main.allow-circular-references

如果有nacos的使用,版本替换为:

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.0.4.0</version>
</dependency>

同时需要支持yml配置,添加 spring.config.import

spring:
  profiles:
    active: "@profileActive@"
  application:
    name: saas
  cloud:
    nacos:
      server-addr: xx.xx.xx.xx:8848
      discovery:
        server-addr: xx.xx.xx.xx:8848
        namespace: f8f5c0c4-adc9-4c37-be6b-ddc
      config:
        server-addr: xx.xx.xx.xx:8848  #配置中心
        file-extension: yaml   #配置文件后缀名   dataId = application.name  +  file-extension
        namespace: f8f5c0c4-adc9-4c37-be6b-ddc
  config:
    import:
      - optional:nacos:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} #配置中心

报错问题定位思路

启动报错:

Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

最开始搜索报错,很多网上说的一般都是忘记加注解@SpringBootApplication,或者没有引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

但是检查并没有遗漏。开始根据问题本身进行定位。

报错本身就是没有找到ServletWebServerFactory,那么思路就是检查xxxxxxxConfiguration中的代码是否正常执行,这里就是org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration

因为是Tomcat方式启动所以只需要关心tomcatServletWebServerFactory方法

这里我设置了debug的方式但是并没有走到这里

再次全局搜索怀疑可能是自动装配的类org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration有问题

再次尝试debug发现依然没有走到,继续思考查看类上方相关的Conditional注解条件是否满足,猜测可能是@ConditionalOnWebApplication(type = Type.SERVLET)不满足

点进注解查看

继续查看对应的org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition,搜索刚才的相关的SERVLET,继续debug发现type为null直接返回了

继续查找调用的地方进行debug发现autoConfigurationMetadata传入的就有问题,很多value都是空字符串

继续定位到上级调用,发现传入的数据依然和上面一样存在问题

继续跟踪定位,终于调到了我们自己写的代码了

继续查看上级调用,发现这个类是我们自己拷贝出来的Springboot内部的类,做了一些自定义的改造

这里就说明,可能是从低版本的Springboot中拷贝出来的,但是升级到2.7.x之后可能存在对应的逻辑变化,所以需要对比一下,大概是哪些代码不一致

Ctrl+A全选Ctrl+C复制我们自己写的代码,然后跳进内部的AutoConfigurationImportSelector再进行比较

这里发现我们自己的代码少了一行

ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add);

根据断言可以知道对应的这段代码不仅是读取了META-INF/spring.factories中的自动装配信息,还读取了META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中的自动装配的bean

最后查看了包结构,确实如此,升级后META-INF/spring.factories没有了ServletWebServerFactoryAutoConfiguration而是放到了META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中。最后解决就是复制对应的代码到自定义的类中,支持imports中的自动装配

更多推荐

【MATLAB】【函数介绍】cp2tform函数从控制点对推断空间变换

官方链接:https://ww2.mathworks.cn/help/images/ref/cp2tform.html?s_tid=doc_ta.cp2tform函数的作用是根据传入的控制点对的坐标推断空间变换参数。函数语法如下:从控制点对推断空间变换,并将此变换作为tform结构返回,有些转换类型具有可选的富家参数t

【EasyExcel】excel表格的导入和导出

【EasyExcel】excel表格的导入和导出【一】EasyExcel简介【二】EasyExcel使用【1】EasyExcel相关依赖【2】写Excel(1)最简单的写(方式一)(2)最简单的写(方式二)(3)排除模型中的属性字段(4)向表格中导出指定属性(5)插入指定的列(6)复杂头数据写入(7)重复写到Excel

c++用dijkstra堆优化版求严格次短路(洛谷p2865)acwing(Tle)版本

先看原题:贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。贝茜所在的乡村有R(1\leR\le10^5)R(1≤R≤105)条双向道路,每条路都联结了所有的N(1\leN\le50

理解Spring原理 - 手写IOC和DI

理解Spring原理-手写IOC回顾Java反射自定义User类:自定义UserTest类:实现Spring的IOC本文完整资源包,懒得一步步操作的同学可以移步下载:CSDN资源-手写IOC和DI完整代码下载回顾Java反射我们都知道,Spring框架的IOC是基于Java的反射机制实现的,下面我们先回顾一下Java反

国产系统适配——kylin安装32位老linux程序方法

运维过程中很多老程序是32位,只能在很老的linux上跑,有没有办法在kylin操作系统上跑呢?实测可以解决,具体如下:1、判断一个程序能否在某个操作系统上运行,可通过执行ldd进程名判断是否能运行或缺失动态库。lddsyncfile报notadynamicexecutable(不是动态可执行文件)或出现notfoun

吐槽一下上周看过的119份简历。

作者:阿秀InterviewGuide大厂面试真题网站:https://top.interviewguide.cn这是阿秀的第「308」篇原创小伙伴们大家好,我是阿秀。以前就分享过写简历的文章:一份百投百中的计算机校招简历是如何迭代足足26版的?、但从最近我修改的一些简历来看,还是有很多小伙伴不会写简历,合格的相当少,

基本的SELECT语句——“MySQL数据库”

各位CSDN的uu们好呀,好久没有更新小雅兰的MySQL数据库专栏啦,接下来一段时间,小雅兰都会更新MySQL数据库的知识,下面,让我们进入今天的主题吧——基本的SELECT语句!!!SQL概述SQL语言的规则与规范基本的SELECT语句显示表结构过滤数据SQL概述SQL背景知识1946年,世界上第一台电脑诞生,如今,

金融行业如何利用软文营销进行品牌维护

金融行业作为强监管行业,与人民财产息息相关,因此塑造可靠的品牌形象是金融行业必须面对的课题,而金融行业的特性决定了它在品牌传播与建设上会受到一定的限制,因此金融行业想要进行品牌维护的话,软文营销就是非常不错的手段,下面就让媒介盒子告诉大家,金融行业应该如何利用软文营销维护品牌形象。一、&nbsp;进行品牌定位进行软文推

从统计语言模型到预训练语言模型---预训练语言模型(Transformer)

预训练模型的概念在计算机视觉领域并不陌生,通常我们可以在大规模图像数据集上预先训练出一个通用模型,之后再迁移到类似的具体任务上去,这样在减少对图像样本需求的同时,也加速了模型的开发速度。计算机视觉领域采用ImageNet对模型进行一次预选训练,使得模型可以通过海量图像充分学习如何提取特征,然后再根据任务目标进行模型精调

针对 SAP 的增强现实技术

增强现实技术是对现实世界的一种交互式模拟。这种功能受到各种企业和制造商的欢迎,因为它可以减少生产停机时间、快速发现问题并维护流程,从而提高运营效率。许多安卓应用都在探索增强现实技术。使用增强现实技术(AR)的LiquidUI可以让SAP用户通过粗略分类来检测和识别多个对象,从而构建实时可视化搜索体验。因此,可以为用户提

Solid框架节点级响应性

前言随着组件化、响应式、虚拟DOM等技术思想引领着前端开发的潮流,相关的技术框架大行其道,就以目前主流的Vue、React框架来说,它们都基于组件化、响应式、虚拟DOM等技术思想的实现,但是具有不同开发使用方式以及实现原理,这里就不再赘述了相关内容,这里关注的焦点在于虚拟DOM。无论是Vue还是React都应用虚拟DO

热文推荐