ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Maven实战:Spring项目依赖管理与冲突排查全攻略

Maven实战:Spring项目依赖管理与冲突排查全攻略 不管你是刚入行的Java新人还是被各种诡异依赖问题折磨过的老手只要你在用Spring写项目就一定绕不开Maven。Maven和Spring的关系就像汽车和发动机的关系——Spring负责提供各种能力而Maven负责把这些能力安全、准确地装配到你的项目里。这篇文章我只讲实操从环境配置到依赖冲突排查每一块都是真实项目里会踩的坑。先说清楚一个概念Maven是构建工具也是依赖管理工具Spring是一个庞大的生态。市面上常见的Spring Framework、Spring Boot、Spring Cloud每个都有几十个模块模块之间还有版本关联。如果靠手动下载jar包往项目里塞两周之后你自己都记不住放了多少个包进去。Maven做的就是把这件事标准化统一目录结构、统一构建流程、统一依赖坐标让你一句话就能拉齐整个Spring生态的依赖。这篇文章适合所有使用Maven管理Spring项目的开发者尤其是刚开始搭建Spring Boot工程、或者已经遇到“依赖包版本冲突”“jar包下载不下来”这类问题的人。我会把你可能遇到的坑都摆出来一个一个拆给你看。1. 先搞清楚一件事Maven到底在解决什么问题1.1 没有Maven之前Java项目的依赖管理有多痛苦我当年刚入行的时候公司老项目还是用最原始的方式管理依赖手动下载jar包扔进WEB-INF/lib目录然后通过IDE的Build Path把它们加进去。新同事入职光配开发环境就要配三天因为每个人的IDE版本不同、JDK版本不同、jar包版本也不同。你本地跑得好好的代码换一台机器就报ClassNotFoundException查半天发现是某个jar包版本不对。那时候项目里有一个Excel导出的功能依赖了poi的3.14版本。后来有人要引入一个报表组件那个组件内部依赖poi的3.17版本。两个版本同时出现在lib目录下JVM加载类的时候完全看心情有时候跑得好好的有时候突然抛一个NoSuchMethodError。这种问题查起来极度痛苦因为你没法确定JVM到底加载了哪个版本的类。这就是Maven出现的根本原因Java项目需要一个统一的依赖管理机制把“下载什么包、下载什么版本、传递依赖哪些包、各模块之间怎么组织”这些问题规范化。1.2 Maven的核心三板斧坐标、仓库、约定Maven解决依赖问题的思路非常朴素就三个概念第一是坐标。每个jar包都有一个唯一标识就像人的身份证号。坐标由groupId、artifactId、version三部分组成。比如Spring Web MVC的坐标是org.springframework:spring-webmvc:6.1.4。有了坐标Maven就能精确找到对应的jar包绝不会再出现“这个包到底是哪个版本”的模糊情况。第二是仓库。Maven把jar包统一放到仓库里管理。本地仓库是你电脑上的一个目录默认在~/.m2/repository下下载过的jar包都存在这里下次再用就直接从本地读取不需要重复下载。远程仓库是服务器上的jar包集合最著名的就是Maven中央仓库Spring官方发布的jar包都会同步到那里。除了中央仓库很多公司会搭建自己的私有仓库比如Nexus用来存放内部公共组件。第三是约定优于配置。Maven强制规定了项目的目录结构Java源码放src/main/java配置文件放src/main/resources测试代码放src/test/java。这样做的好处是不管谁接手项目都能在第一时间找到对应文件不需要花时间理解项目的自定义结构。这三板斧组合起来就让Spring的依赖管理变成了一件极其省心的事你在pom.xml里声明需要哪些依赖Maven自动从仓库下载自动处理传递依赖自动将jar包引入编译和运行环境。2. 环境准备Maven安装配置与国内镜像加速2.1 下载安装与环境变量配置配置Maven之前先检查一下JDK版本。这里有一个很容易踩的坑Spring Boot 3.x要求JDK 17及以上Spring Boot 2.x可以用JDK 8或11。Maven本身也有版本要求Maven 3.9支持JDK 8到JDK 21建议直接下载最新的Maven 3.9.x版本兼容性最好。下载Maven就是去Apache Maven官网找到apache-maven-3.9.x-bin.zip文件。注意要下载bin版本不要下src版本src是源码包普通开发用不到。下载完成后解压然后把MAVEN_HOME配置到环境变量里。Windows下在系统变量里新建MAVEN_HOME指向解压目录然后在Path里加上%MAVEN_HOME%\bin。Mac和Linux用户需要在~/.bashrc或~/.zshrc里加一行export MAVEN_HOME/opt/apache-maven-3.9.9 export PATH$MAVEN_HOME/bin:$PATH配置完成后在命令行输入mvn -v能输出版本信息就说明安装成功了。注意看输出里的Java version如果显示的不是你期望的JDK版本多半是JAVA_HOME环境变量没有指向正确的JDK路径把JAVA_HOME改掉就行。2.2 settings.xml里必改的三个地方Maven的全局配置文件叫settings.xml位置在$MAVEN_HOME/conf下。还有一个用户级别的settings.xml位置在~/.m2/settings.xml用户级别的优先级高于全局级别实际项目里推荐把用户配置文件放~/.m2下这样即使Maven升级了配置也不会丢。settings.xml里最重要的三个配置项是localRepository、mirror和profile。localRepository就是本地仓库路径默认是~/.m2/repository。这个路径有一个隐患如果你的系统盘是SSD但空间不大几百个jar包塞进去会占掉好几个G。我一般会在D盘或数据盘建一个专门的目录比如D:\maven-repository然后在settings.xml里改成localRepositoryD:\maven-repository/localRepositorymirror就是镜像配置。Maven默认从中央仓库下载文件但中央仓库的服务器在国外国内网络环境下下载速度非常慢。我之前有一次构建Spring Boot项目光下载依赖就花了快半个小时。后来配置了阿里云镜像同样的项目两分钟就完成了。profile可以配置JDK版本和激活方式这个后面会细说。2.3 阿里云中央仓库镜像配置教程镜像配置直接写在settings.xml的mirror标签里。在mirrors节点下添加mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirrormirrorOf标成central的意思是所有从中央仓库发起的下载请求都会走这个镜像。如果公司有私有仓库也可以把mirrorOf配置成*,!private-repo意思是除私有仓库外都走镜像。这里有一个细节需要提醒不要把所有镜像地址都配成同一个。https://maven.aliyun.com/repository/public其实已经聚合了central和jcenter的内容日常开发够用了。如果你用的是Spring Boot项目可能还需要额外配置Spring的里程碑仓库milestone和快照仓库snapshot在项目的pom.xml里加repositories节点repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories不配置这个的话如果你用到Spring的某个RCRelease Candidate版本或者里程碑版本Maven会直接报Could not find artifact错误。这也是一个很典型的坑很多人用的是Spring Boot 2.7的RC版本跑构建就报依赖找不到其实就是没加这个仓库。3. pom.xml里Spring依赖包的正确配置方法3.1 spring-boot-starter-parent版本管理的定海神针你新建一个Spring Boot项目的时候pom.xml里第一行使用的parent一定长这样parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.4/version relativePath/ /parent这个东西极其重要。Spring Boot官方把整个Spring生态的版本都固化在这个parent里了。比如spring-boot-starter-parent:3.2.4对应的Spring Framework版本是6.1.5对应的Spring Security版本是6.2.3。你只管在你自己的项目里写依赖坐标不需要写版本号parent会帮你把所有版本对齐。这招叫依赖版本集中管理。如果不用parent你自己手写版本号很容易写出这种情况spring-boot-starter-web是2.7.5spring-security-config是6.1.2spring-jdbc还是4.3.20——这几个版本根本不兼容运行的时候各种神奇的错误都会冒出来。我强烈建议只要你是Spring Boot项目一定基于spring-boot-starter-parent构建不要自创一套不依赖parent的管理方式。自创版本管理不是不行但那是架构师级别要考虑的事普通项目用parent就好。3.2 核心依赖如何正确写入pom.xml写Spring依赖时推荐的做法是只用spring-boot-starter-*这种简化坐标。比如要开发Web项目dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency这样一个依赖就会把Spring MVC、内嵌Tomcat、Jackson JSON处理、Spring Core等一堆相关的jar包都带进来。你不需要自己去写spring-webmvc、spring-core这些细粒度的依赖少了哪一个Maven都会在构建时报错很让人抓狂。用到了数据库那就加上dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency或者如果是MyBatisdependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version3.0.3/version /dependency注意像mybatis-spring-boot-starter这种不是Spring官方出的starterparent里不会管它的版本所以必须自己声明version。这是很多新人搞不清楚的地方凡是org.springframework.boot开头的坐标版本都不写凡是第三方starter比如MyBatis、Druid、Lombok的版本都要自己写清楚。3.3 scope和依赖传递什么时候要设置依赖范围pom.xml里每一项依赖都可以设置scope它决定依赖的生命周期。用最直白的话说compile默认值打包的时候要带上运行的时候也要带上比如spring-boot-starter-web。provided编译和测试需要运行和打包的时候不需要因为运行环境已经提供了。典型例子是Servlet API因为Tomcat容器里自带。runtime编译不需要运行需要。很少见JSP引擎类库属于这一类。test只在测试代码中有效比如JUnit、Spring Boot Test。system当你非得引用一个不在Maven仓库里的本地jar包时才用绝大多数情况下千万别用。有一种典型错误是把JUnit的scope写成了compile结果打出来的生产包大几百兆全是没用的测试库。我见过一个同事把spring-boot-starter-test的scope写成默认部署到服务器后发现应用内存占用异常大排查了半天最后发现是测试库一堆包都进去了。所以测试类依赖记得加上dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency关于依赖传递我讲一个最简单的原则你声明的依赖会把它自己的依赖也传递到你的项目里。比如你引入spring-boot-starter-web它内部的spring-webmvc、jackson-databind都会自动出现在你的类路径里。这个机制极大方便了使用但也诱发了版本冲突。这是下一章的重点。3.4 dependencyManagement统一的版本锁如果你想自己接管版本控制可以不继承parent而是在pom.xml里用dependencyManagement统一管理版本。这个机制在multimodule多模块项目中特别常用。主pom.xml里声明dependencyManagement dependencies dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-dependencies/artifactId version2023.0.1/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement这样各个子模块里使用Spring Cloud的依赖时就不用写版本号了。import这种scope是一个特殊用法它表示把我声明的这个BOMBill of Materials材料清单里的依赖管理信息导入进来相当于一次性获得一整批版本推荐。最知名的BOM就是spring-cloud-dependencies和spring-boot-dependencies。Spring Cloud每个版本对应一批微服务组件版本直接引入它就等于你把整个微服务体系的版本都对齐了。若依RuoYi框架的后端也是这么做的把Spring Boot和Spring Cloud的版本都交给parent和dependencyManagement统一管理。4. 依赖包版本冲突高频事故现场与排查方法4.1 冲突到底是怎么发生的依赖冲突本质上是因为Maven的传递依赖机制太强大了。你的项目引入了AA引入了BB引入了CC里面可能又引入了你自己的某个依赖——多级传递之后同一个jar包可能同时出现好几个版本。有一个真实的场景项目用了Spring Boot 2.7.5对应的Spring Framework版本是5.3.23。后来接入了一个公司内部的公共组件这个组件是老项目里抽出来的它内部依赖了Spring Framework 5.2.15。这时候你的工程里就同时存在5.2.15和5.3.23两个版本的Spring核心类。虽然Maven会做一个“最近优先”的版本选择但版本冲突的隐患就此埋下了新版本的类有某个方法而旧版本的类没有这个方法运行到那里就报NoSuchMethodError。这种错误非常阴险编译期完全没有提示因为你编译的时候Maven选中了新版本的jar包方法存在编译通过。但是运行时因为某种加载顺序问题JVM可能加载到了旧版本类运行时直接崩溃。4.2 如何快速确定是哪个版本在打架排查依赖冲突不能靠猜要借助工具观察“依赖树”。Maven自带的命令是mvn dependency:tree这个命令会输出整个项目的依赖树每一行是一个依赖坐标。配合-Dverbose参数可以看到更详细的信息。如果要专门查某个jar包的来源mvn dependency:tree -Dincludesorg.springframework:spring-core-Dincludes后面可以跟groupId或artifactIdMaven会过滤出所有与这个坐标相关的依赖路径。比如输出长这样[INFO] com.example:my-project:jar:1.0.0 [INFO] - org.springframework.boot:spring-boot-starter-web:jar:2.7.5:compile [INFO] | \- org.springframework:spring-webmvc:jar:5.3.23:compile [INFO] \- com.company:internal-component:jar:3.2.1:compile [INFO] \- org.springframework:spring-core:jar:5.2.15:compile肉眼看这个树状结构你就能发现spring-core同时存在5.3.23和5.2.15两个版本。如果你用IDEA开发更推荐装一个插件叫Maven Helper。在pom.xml的Dependency Analyzer标签页里可以可视化地看到哪些依赖存在冲突哪些版本被Maven解析到了哪些被剔除了。这个插件还能一键排除冲突依赖极大提升排查效率。4.3 解决冲突的三种手段第一种是排除传递依赖——在dependency里加exclusions标签dependency groupIdcom.company/groupId artifactIdinternal-component/artifactId version3.2.1/version exclusions exclusion groupIdorg.springframework/groupId artifactIdspring-core/artifactId /exclusion /exclusions /dependency意思是引入internal-component的时候把它传递过来的spring-core排除掉。这样Maven就会用你项目里已有的、由Spring Boot parent管理的5.3.23版本冲突自然消失。第二种是在dependencyManagement里强制指定版本。这种手段适合在公司统一管理依赖的场景。在父pom的dependencyManagement里写dependencyManagement dependencies dependency groupIdorg.springframework/groupId artifactIdspring-core/artifactId version5.3.23/version /dependency /dependencies /dependencyManagement这样无论在哪个子模块里spring-core都统一使用5.3.23。第三种是修改本项目的依赖声明让自己声明的坐标与实际的版本保持完全一致。很多时候冲突本身就是因为你自己写错了版本号比如本来Spring Boot 2.7.5对应Spring Framework 5.3.23你偏要强写5.2.15版本当然会对不齐。把所有spring开头的坐标版本号全部删掉完全交由parent管理才是根治方案。这三种手段排优先级的话能用第三种就先用第三种不行就用第一种exclusion做局部排除最后才用dominant全局强制版本。因为强制版本可能引入新的不兼容风险需要回归测试支持。4.4 版本冲突的常见连锁反应依赖冲突的报错不止NoSuchMethodError一种还有可能是ClassNotFoundException、NoClassDefFoundError。这里科普一下区分方法ClassNotFoundException是类根本没有出现在类路径上一般是jar包没有引入或者被排除了运行时JVM找不到这个类NoClassDefFoundError是类按名字存在但加载的时候失败更多时候是依赖了同一个类的不同版本导致某个字段或方法缺失了。看到这两类错误第一反应就应该是去查依赖树。除了代码层面的报错冲突有时还表现为启动时日志里有警告。Spring Boot启动时输出一行“The use of package scanning conflicts with non-explicit class...”或者类似提示这种信息一般不会让应用起不来但也说明你的依赖里存在未版本对齐的组件长期维护会有隐患。比如Spring Security和Spring Framework版本不对齐启动时就会出现Failed to introspect Class这种警告极大概率是spring-security的版本比spring-core老两者不兼容。5. 那些年踩过的坑从Maven小白的崩溃瞬间到老手的避坑手册5.1 构建时下载依赖一直卡住或超时这个问题八成和网络有关。这里先排除一个最容易犯的错误每次修改settings.xml之后IDEA不会自动重载配置需要重新打开Maven面板点刷新按钮或者重启IDEA。不然你明明改了镜像地址构建还是走默认的中央仓库下载速度当然慢。如果你已经正确配置了阿里云镜像发现还是慢那就看一眼本地仓库是否出现了半截文件。Maven下载中断后本地仓库会残留一个.lastUpdated结尾的文件这个文件会导致Maven下次不再重新下载而是直接判定Could not resolve dependencies。处理方式是直接删掉本地仓库中对应的目录一般路径是D:\maven-repository\org\springframework下的某个子目录删完重新构建Maven会强制重新下载。5.2 本地仓库的jar包被污染怎么办还有一种“灵异现象”某个jar包明明在本地仓库存在但Maven还是报Missing artifact。这通常是因为本地仓库里的_remote.repositories文件记录了上次下载时的仓库ID换了镜像地址或换了仓库后Maven认为这个本地文件与当前仓库不一致拒绝使用。解决办法有两个要么删掉_remote.repositories文件要么直接删掉对应目录重新下载。这个文件删掉不会影响jar包使用我实测过多次删完构建就能过。5.3 使用IDEA时热部署和依赖不生效IDEA里经常会遇到一种情况pom.xml里加了新依赖代码里也能正常import但运行时一直提示ClassNotFound。这种问题多了一半原因在于IDEA的缓存。解决方案是Maven面板里的Lifecycle点一下clean然后执行install再重启项目。另外如果是多模块项目推荐在IDEA的Maven设置里勾选“Always update snapshots”。Spring、若依框架这类经常更新快照版本的工程如果不开启这个选项本地引用到的快照版本永远不会更新改代码后看不到效果排查半天发现不是自己代码的问题而是依赖没更新。5.4 install和package的区别别再搞混了命令行构建Spring项目用的最多的两个命令是mvn clean install和mvn clean package。很多人以为它们效果一样其实差很远。package只将当前项目的产物打包成jar或war而install除了打包还会把当前项目的jar安装到本地仓库。如果你有多个模块模块A依赖模块B模块B修改了代码必须执行mvn install把新版本的B装入本地仓库否则A的运行环境里还是旧版本的B。我第一次接触若依框架的时候就是这个坑改了后台的system模块前端admin模块怎么都不生效后来才明白必须先install核心模块。这个经验后来在做任何多模块项目时都适用记住一条原则**本地依赖的模块修改后必须先用mvn install。5.5 各种Spring模块常见版本匹配参考说了这么多直接给出一张常见的Spring生态版本对应参考表方便你排查版本时对照。场景Spring Boot版本Spring Framework版本Spring Cloud版本推荐JDK老项目维护2.5.x5.3.x2020.0.5 / 2021.0.x8 / 11常规新项目2.7.x5.3.x2021.0.x8 / 11 / 17新项目推荐3.2.x6.1.x2023.0.x17 / 21微服务新项目3.1.x6.0.x2022.0.x17 / 21这组数据不需要死记但你心里要有概念。比如Spring Boot 2.7对应的Spring Cloud是2021.0.x也叫Jubilee如果自己把Spring Cloud版本改成2022.0.x大概率会因为依赖的Spring Framework版本冲突而启动失败。遇到这种情况全部改回来也不要相信网上说“可以混用”的帖子自己动手实验过的人才知道混用会搞出多少幺蛾子。5.6 快照版本和正式版本的使用原则Maven里版本号带-SNAPSHOT后缀表示快照版本比如spring-cloud-starter-alibaba-nacos-discovery:2023.0.0-SNAPSHOT表示还处于开发中的版本。这类版本发布不稳定同一个版本号每天可能会更新好几次。生产环境的项目一律不要使用SNAPSHOT版本因为今天构建成功明天再构建可能就是完全不同的代码行为。如果非要用那就锁死仓库里的一个时间点或者干脆用release版本。在Maven配置里为了加速开发你可以在settings.xml的profilename开快照更新profiles profile idallow-snapshots/id activation activeByDefaulttrue/activeByDefault /activation repositories repository idsnapshots/id urlhttps://maven.aliyun.com/repository/public/url snapshots enabledtrue/enabled /snapshots /repository /repositories /profile /profiles这里注意一个问题如果同时配置了mirrorAliyun镜像用于中央仓库再把阿里云镜像地址又加到仓库里可能会有冲突。多个repository配置尽量贴合实际需求不要无脑堆。6. 从Maven视角看Spring项目几个必须理解的工作原理6.1 Spring的三级缓存和控制反转和Maven有什么关系很多人学Spring的时候会在“三级缓存”“控制反转”这些概念上卡住。这里我讲一个纯经验层面的联想控制反转IoC的本质是对象之间的依赖由容器管理而Maven的本质是jar包之间的依赖由工具管理。两者是同一个思想在不同层面的体现不让你手工维护复杂依赖关系而是通过一套中央机制自动搞定。Spring在实例化bean时为了避免循环依赖使用了三级缓存一级缓存存的是完全初始化好的单例对象二级缓存存的是提前暴露的早期对象三级缓存存的是对象工厂。如果你之前靠手动new对象拼装复杂系统一旦出现循环引用A引用了BB引用了A程序直接栈溢出崩溃。但Spring通过三级缓存把创建过程分阶段进行从而支持了循环依赖。这和Maven有什么关系其实关系在于理解“依赖图”的概念。Maven构建项目的时候会根据pom.xml生成一张完整的依赖图Spring创建bean的时候也会根据各类注解和配置生成一张对象依赖图。你使用Maven管理Spring依赖时如果理解了pom里的依赖树是怎么组织的反过来你也能更快地理解Spring bean之间是怎么组织依赖关系的。很多人从Maven控制依赖版本过渡到理解Spring三级缓存只差一个“依赖树思维”的转换。6.2 Spring Boot自动配置和Starter依赖的配合Spring Boot之所以能实现开箱即用离不开spring-boot-starter-*依赖和自动配置机制的配合。你引入一个starter依赖Maven把它包含的jar包拉进类路径Spring Boot在启动时会扫描类路径下的META-INF/spring.factories文件加载对应的AutoConfiguration类并根据条件注解ConditionalOnClass、ConditionalOnMissingBean等决定是否启用某些配置。这个机制带来的一个实际影响是你删掉或换掉某个依赖时Spring Boot的自动配置行为也会改变。比如spring-boot-starter-web被排除后Spring MVC的自动配置就不再生效项目里的Controller接口全部无法访问。所以修改依赖时要考虑自动配置的影响面不要觉得删掉一个无关紧要的starter不会出事——它背后可能关联了一大片自动配置。6.3 手写一个“简化版Spring”能帮你更好理解Maven配置网络上很多人推荐通过手写一个简化版Spring容器来学习Spring原理我觉得非常值得试。这里的精华在于你不会一开始就遇到复杂的自动配置而是从零开始用Java反射、注解、类扫描去实现对象注册和依赖注入。当你声明的Component注解能被自己写的扫描器识别时你才能真正理解spring-context这个jar包到底在classpath里做了什么。手写的建议路径是先实现一个IoC容器管理bean的注册与获取再实现Autowired的自动注入最后再去研究Bean生命周期的各个阶段。等你能徒手跑通这一套回过来看Maven的dependency:tree你会发现从前觉得乱成一团的jar包关系变得清晰了哪个模块管理了哪些Bean、依赖了哪些外部库、加载顺序如何全都能对得上号。7. 实操心得如果这个项目重做一遍我会怎么配置Maven最后分享一点我个人实际使用Maven管理Spring项目的体会。如果你是第一次搭建一个新项目不要一上来就各种拷贝网上五花八门的pom配置我的建议是第一步直接从spring-boot-starter-parent作为parent把Spring Boot版本确定为当前稳定版比如3.2.4或2.7.18。第二步按需引入starter依赖Web、测试、数据库、Redis、消息队列缺什么加什么。第三步配置好settings.xml的阿里云镜像和本地仓库路径确保团队每个人环境一致。第四步写好README里的Maven构建说明明确团队统一用mvn clean install构建统一JDK版本。这样的方案也许看起来普通但它是最稳的。普通项目追求的不是炫技而是团队成员之间不互相踩坑。Maven这个工具的哲学本来就是“约定优于配置”你强行加入各种自定义插件、自定义依赖过滤、自定义仓库策略短期内可能解决了某个具体问题长期看增加了所有人的维护成本。最后再分享一个实用小技巧每次大版本升级Spring Boot时先在mvn dependency:tree里对比升级前后的依赖树变化重点关注哪些jar包的版本被改了哪些子依赖被升级了。我前年从Spring Boot 2.6升到2.7时就是这样先找出所有版本变化的组件再重点测试这些组件对应的功能最终整个升级过程只花了半天时间上线后也没有出现任何异常。这个习惯我一直保留也希望你们用得上。
返回列表