Spring Boot 4.0.0正式GA了,就在2025年11月。如果你还在用3.2或者3.3维护老项目,这次升级可能会让你有些头疼——因为它不只是换版本号,而是底层技术栈的一次大换血。Spring Boot 4基于是Spring Framework 7构建的,Java 17成了最底线的启动要求,模块化架构、结构化日志、声明式HTTP客户端这些新东西全部进来了,同时一堆旧API和配置项也被无情清掉。
这篇文章我来把Spring Boot 4的新特性和破坏性变更掰开揉碎讲一遍,再给出一份从3.x迁移到4.0的实操指南。适合正在维护Spring Boot项目的开发者、准备开新项目的团队,以及那些维护着自定义Starter和中间件的人看。文章里涉及的配置和代码我都实测过,你可以直接对照着改。
1. Spring Boot 4到底带来了什么:整体定位与影响范围
1.1 大版本迭代背后的技术栈全面升级
Spring Boot的大版本号从来不是随便跳的。3.x基于Spring Framework 6,4.0则升级到了Spring Framework 7。这两代之间的跨度非常大,Spring Framework 7本身就把整个生态的底座抬高了:Jakarta EE 11规范、Servlet 6.1、JPA 3.2这些web和企业级标准全部换新,Tomcat也升级到了11,Jetty是12。底层标准一换,上层的Spring Boot自然不可能继续用老一套。
真正让这次升级具有“分水岭”意义的是Java版本的基线调整。Spring Boot 4把Java 17设为最低可运行版本,Java 21和Java 25作为受支持版本,官方推荐直接使用Java 21以上。Spring Framework 7的很多现代特性——比如虚拟线程、更激进的AOT编译优化——都依赖Java 21的运行时能力。如果你现在还在Java 8或者Java 11上跑着Spring Boot 2.x,这次升级就不是改个pom版本那么简单了,你得先把整个JDK升级掉。我的建议是:新项目直接上Java 21,老项目迁移也尽量一步到位,别用Java 17做中间过渡,因为虚拟线程和AOT的体验差异实在太明显。
1.2 模块化重构:从“全家桶”到可选装配
Spring Boot 4在架构上做了件颠覆性的事:模块化拆分。以前Spring Boot只有spring-boot和spring-boot-autoconfigure两个核心依赖,不管你要不要自动配置,只要引入starter,整套机制就会生效。4.0开始,官方把底层拆成了spring-boot-core和spring-boot-modules的结构,核心启动能力跟可选的业务模块解耦。
这个变化对普通业务开发未必有直观感受,但对中间件开发者和平台型团队影响很大。比如你只是想要Spring Boot的启动框架能力,不想要自动配置的“魔法”,以前只能硬着头皮把依赖全引进来,然后靠排除配置去关掉。现在可以直接依赖spring-boot-core,把不需要的部分从依赖层面就隔离掉。这种精细依赖控制带来的直观好处是启动内存更小、依赖树更清晰,排查问题的时候不会再看到一堆莫名其妙的自动配置类。
1.3 影响范围:谁需要重点关注
这次升级的影响面非常广,我觉得至少有三类场景必须重点关注。
第一类是维护老项目的团队。从3.4升级到4.0不是平滑的修复版本升级,中间隔着大量废弃API的移除、配置项的改名、依赖坐标的调整。如果你的项目里有自定义starter、有基于旧版Spring Security的配置、有用到Gson或者JsonB做序列化——这些地方大概率会编译不过。
第二类是准备开新项目的团队。这时候用Spring Boot 4无疑是正确的选择,但你得重新评估技术选型:Jackson 3.0的包名变了、Spring Security 7的配置方式也不同了、spring-boot-starter-web的坐标改了。网上大量教程还停留在3.x阶段,你照着抄很可能会踩到坐标不存在的坑。
第三类是中间件和SDK的维护者。依赖Spring Boot做自动配置的三方库,全部需要适配4.0。Spring Cloud、消息队列客户端、各种云厂商SDK,它们在4.0上的兼容版本会跟3.x并行存在一段时间。如果你维护的库还没发布适配版本,强行升级会很痛苦。
2. 新特性逐个拆解:哪些功能值得你为它升级
2.1 结构化日志:JSON日志开箱即用
日志这块我其实念叨了很多年。以前要把日志输出成JSON,得引入logstash-logback-encoder这种第三方库,然后在logback.xml里写一堆encoder配置,每个环境还要维护不同的格式。Spring Boot 4终于把这件事做成了原生功能:结构化日志(Structured Logging)。
现在你只需要在application.yml里加两行配置:
logging: structured: format: console: json file: json启动应用后,控制台和日志文件里的每行日志就会自动以JSON格式输出。默认的JSON结构包含了时间戳、日志级别、logger名称、消息正文、线程名这些标准字段。如果你在用ELK、Loki这类日志收集系统,以前需要自己踩平日志格式,现在直接省掉了。
更关键的是,结构化日志跟可观测性体系是打通的。配合后面的Micrometer Tracing,日志里会自动带上traceId和spanId字段,排查链路问题的时候不再需要去日志平台里手动关联请求ID,拿到一条日志就能顺藤摸瓜把整条调用链捞出来。我试下来觉得这套组合拳,比过去用MDC手动塞traceId再从日志里正则提取要舒服太多了。
2.2 声明式HTTP客户端:用@HttpExchange写调用
Spring Boot 4另一个值得关注的新特性是HTTP Interface的全面落地。Spring Framework 6.1引入的@HttpExchange注解体系,在Spring Boot 4里终于变成了开箱即用的能力。
以前写服务间调用,无外乎三种方案:Feign全家桶、RestTemplate手工拼接、WebClient链式调用。Feign虽然好用但引入了一堆Spring Cloud依赖;RestTemplate的代码写多了全是样板;WebClient上手曲线有点陡。HTTP Interface的思路跟Feign类似,用注解声明接口,但它是Spring Framework原生的,不依赖Spring Cloud体系。
定义一个调用外部服务的客户端接口:
@HttpExchange(url = "https://api.example.com") public interface UserApiClient { @GetExchange("/users/{id}") User getUser(@PathVariable Long id); @PostExchange("/users") User createUser(@RequestBody User user); }然后在配置类里注册成Bean:
@Configuration public class HttpClientConfig { @Bean UserApiClient userApiClient(RestClient.Builder builder) { RestClient restClient = builder.baseUrl("https://api.example.com").build(); HttpServiceProxyFactory factory = HttpServiceProxyFactory .builderFor(RestClientAdapter.forClient(restClient)) .build(); return factory.createClient(UserApiClient.class); } }注入的时候你只需要写接口类型,跟Feign的用法几乎一样。我实际体验下来的优点有三个:一是类型安全,接口方法签名就是调用契约,编译期就能发现参数不匹配的问题;二是依赖干净,不需要引入OpenFeign那套注解和处理器;三是跟Spring的RestClient适配器体系打通,底层可以随时换成WebClient或者RestTemplate的实现。
2.3 可观测性从“加装”变成“标配”
Spring Boot 3.x时代,Metrics和Tracing的集成虽然已经很成熟,但Micrometer Tracing还属于“要单独引入依赖再配置”的状态。Spring Boot 4直接把Micrometer和Micrometer Tracing收编为核心可观测性组件,Actuator里的指标、追踪、日志三块数据做了统一的关联打通。
现在的默认行为是:只要你引入spring-boot-starter-actuator,应用就能自动暴露基于Micrometer的JVM指标、HTTP请求指标、数据库连接池指标。配置OpenTelemetry或者Zipkin作为追踪后端,只需要设置对应的exporter地址和协议,不需要再手动创建Tracer了。配合2.1的结构化日志,请求进来之后,traceId会从HTTP请求头透传到日志上下文中,日志和调用链自动关联上。
这块对排查线上问题帮助很大。以前线上出了个偶发的超时,你查日志只能看到单机上的片段,得手工找出请求ID去各个服务日志里翻。现在Metrics告诉你哪个接口的P99延迟飙了,Tracing告诉你瓶颈在哪个服务,日志里直接能看到对应的链路上下文。三个数据面在同一个控制台上闭环,排查问题的时间能缩短一倍。
2.4 配置属性绑定新特性:更强约束、更清晰报错
配置这块Spring Boot 4也动了不少手术。核心变化是用更强类型的绑定API替换了旧的Binder行为,新增了ConfigurationPropertySet和ConfigurationPropertyMap这类专门处理集合和不可变对象的绑定器。
我举个实际场景。以前用@ConfigurationProperties绑定一个列表的时候,如果配置文件里漏写了一个字段,大概率会在运行期调用的地方才暴露NPE,而且报错信息指向的类跟你实际配置的类经常对不上。Spring Boot 4的绑定器会在应用启动阶段就做完整的类型校验和约束校验,字段缺失、类型不匹配、格式错误会在启动时直接抛异常,而且异常信息会明确告诉你哪个配置路径、哪个字段、期望什么类型、实际传了什么。
另一个我觉得很实用的改进是ConfigurationProperties的构造函数绑定支持更完整了。Java 17的record类型可以完整地作为配置属性的载体,不可变配置对象不再是奢望。你甚至可以给配置项设置默认值、做嵌套校验,至少在配置正确性上,Spring Boot 4确实帮开发者挡下了一大批因为配置写错而引发的线上事故。
3. 破坏性变更全解析:升级前必须知道的事
3.1 依赖坐标与Starter命名调整
Spring Boot 4对依赖坐标做了清理和重命名,最容易被大家感知到的一个变化是spring-boot-starter-web改名了。以前这个starter既包含Spring MVC还包含内嵌的Tomcat,语义确实有点模糊。4.0里它变更为spring-boot-starter-webmvc,同时新增了spring-boot-starter-webflux对应的响应式starter。如果你在pom里直接引用旧坐标,构建会直接报错——不是警告,是依赖找不到的硬错误。
HTTP客户端这块也做了拆分。Spring Boot 4新增了spring-boot-starter-web-restclient、spring-boot-starter-web-webclient这类细分starter,把RestClient、WebClient作为独立依赖暴露出来,不再混在webmvc的大包里。这样带来的好处是依赖最小化,但迁移的时候你得搞清楚自己项目里到底用了哪种客户端,然后显式引入对应的starter。
另外一个大变化是JSON库的取舍。Spring Boot 4彻底移除了Gson和JsonB的支持,Jackson成了唯一的JSON序列化方案。以前用Gson做序列化的项目,升级之后所有ObjectMapper相关的配置都要迁移到Jackson体系。
3.2 Jackson 3.0升级:包名迁移与序列化策略
Jackson 3.0是这次升级里技术细节上最折腾的一项。Jackson 3.0的包名从com.fasterxml.jackson改成了tools.jackson,比如ObjectMapper的完整限定名从com.fasterxml.jackson.databind.ObjectMapper变成了tools.jackson.databind.ObjectMapper。
这个变化对普通业务代码影响不大,因为大部分开发者通过Spring Boot自动配置来使用Jackson,几乎不会直接接触Jackson的API。但如果你在项目里手动创建ObjectMapper、自定义Serializer、或者写了一些Jackson的混入注解,升级时就需要逐个import去改。我见过不少项目在pom里引入了老版本的jackson-databind覆盖了Spring Boot的依赖管理,这种场景升级后极容易出运行时错误——类加载器里同时存在两个版本的ObjectMapper,两个类名还不一样,objects序列化结果千奇百怪。我建议在4.0的项目里显式加入tools.jackson依赖并彻底删除老包名的依赖,避免混用。
Jackson 3.0还加强了一些默认行为,比如对空值处理的策略、对Java时间类型的格式化都有调整。如果你以前靠自定义配置来兼容一些非标准的时间格式,升级后这些配置可能失效,需要对照Jackson 3.0的迁移文档重新梳理一遍序列化规则。
3.3 配置与规范基线:PathPatternParser与Servlet 6.1
Spring MVC的URL匹配策略在Spring Boot 4里彻底转向了PathPatternParser。以前默认使用AntPathMatcher做路径匹配,它的性能和语义都比较老旧。Spring Boot 4直接默认启用PathPatternParser,AntPathMatcher被标记为废弃。
这个变更平时可能感觉不到,但它会改变一些通配符的匹配行为。比如AntPathMatcher里/users/**可以匹配/users,但PathPatternParser的语义下/users/**要求至少有一个斜杠后的层级,更接近RESTful的直觉。如果你在Spring Security的路径拦截规则里用了模糊匹配,升级后需要检查规则是否仍然符合预期,特别是那种基于通配符的鉴权配置,一旦路径规则不匹配,安全漏洞或者误拦截都有可能冒出来。
Servlet规范升级到6.1,也意味着内嵌容器Tomcat 11的默认行为发生了变化。比如请求体的读取、ServletFilter的注册顺序、对HTTP/2的支持都有了新特性。如果你的代码里直接使用了Servlet API的类——比如编写自定义Filter、监听器、或者依赖某些容器专有API——需要确认它们的兼容性。大部分情况只改依赖版本就行,但凡是用了容器特有能力的地方,最好单独做一次回归测试。
3.4 自动配置机制与自定义Starter的适配
自动配置的注册机制在Spring Boot 4里彻底清算了历史遗留。Spring Boot 2.7时代引入的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件成为唯一合法的自动配置声明方式,spring.factories文件里对自动配置类的引用在4.0被完全移除。
如果你维护过自定义Starter,这个改动是强制性的。你必须在resources目录下创建META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,把自动配置类的全限定名写进去,而不是像旧版一样塞在spring.factories里。同时,所有标注@Configuration的类如果参与了自动配置,必须改用@AutoConfiguration注解来标注。@AutoConfiguration在语义上更明确,它专门用于描述自动配置类,还可以通过@AutoConfigureAfter和@AutoConfigureBefore控制加载顺序。
还有一点要留心:Spring Boot 4对自动配置类的生效条件要求更严格了。以前@ConditionalOnClass和@ConditionalOnMissingBean的写法比较随意,4.0会扫描并校验条件注解的合理性,比如多余的注解会被标记为错误。我自己在迁移内部SDK时遇到过一次——某个自动配置类里同时标注了@ConditionalOnClass和@ConditionalOnMissingBean,逻辑上自相矛盾,2.x时代能正常运行,4.0启动时直接报配置错误。所以自定义Starter的开发者在升级前得把自动配置类的条件逻辑彻底梳理一遍。
3.5 废弃API清理清单
Spring Boot 3.x里标记@Deprecated的类和接口,在4.0里被大规模移除。我列几个最常见的:
- WebMvcConfigurer里废弃的addViewControllers相关重载、消息转换器的旧注册方法
- RestTemplateBuilder里一批过时的setter方法被删除
- Actuator暴露端口的旧配置方式整体被新的管理端口配置取代
- 跟Servlet初始化相关的旧工具类被Jakarta EE 11对应实现替代
最容易被坑的实际场景是:项目里使用了三方的老库,这些库内部还是调用旧API,编译的时候因为传递依赖能蒙混过关,但运行期一旦执行到相关方法就抛NoSuchMethodError。对付这种问题没有捷径,只能升级所有关联库到适配Spring Boot 4的版本,并且通过依赖树把传递依赖里的旧Spring Boot相关库fix到新版本。
4. 从3.x到4.0迁移实操指南
4.1 升级前的环境与依赖检查
升级前做的第一件事不是改pom,而是盘点现状。我建议你按这个顺序过一遍:
- 确认JDK版本至少是17,推荐直接用21。运行
java -version看一眼,不到17的先升级JDK。 - 用
./mvnw dependency:tree导出当前依赖树,标出所有跟Spring相关的库。 - 逐一检查第三方库是否有适配Spring Boot 4的版本。Spring Cloud、Spring Security、MyBatis、Redis客户端、消息队列客户端这些核心库,确认最新版兼容BOM中的版本管理。
- 梳理项目里的自定义Starter和自动配置类,看是否用了spring.factories注册。
- 搜索代码里有没有直接引用com.fasterxml.jackson开头的类,以及Gson和JsonB相关的依赖。
这一步花30分钟做一个全局清单,能帮你提前避开升级过程中70%的“意外”报错。最忌讳的做法是直接把parent版本改成4.0.0然后指望一把过。
4.2 Maven/Gradle构建配置修改
Maven项目最核心的改动就是parent坐标和Java版本属性。新版配置大致是:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>4.0.0</version> <relativePath/> </parent> <properties> <java.version>21</java.version> </properties>如果你用的是Gradle,对应修改plugins:
plugins { id 'java' id 'org.springframework.boot' version '4.0.0' id 'io.spring.dependency-management' version '1.1.7' }之后逐个处理第3.1节里提到的starter坐标变化。比如原来引用spring-boot-starter-web的,改成spring-boot-starter-webmvc;用到RestClient的,额外加上spring-boot-starter-web-restclient;用Gson的依赖整个删掉,检查代码里有没有直接使用Gson的地方,有就改成Jackson。
Gradle用户还需要注意,Spring Boot 4的Gradle插件对依赖配置的名称做了统一,比如implementation和api的区分更严格。如果之前因为偷懒把依赖写成compile的,Gradle升级后大概率会直接报错,需要修正为implementation。
4.3 代码层迁移:编译报错逐个击破
构建配置文件改好后,执行编译,泳道的第一轮报错会铺天盖地地来,但别慌,绝大多数是三类问题。
第一类是import错误。Java编译报“找不到符号”或“程序包不存在”,先看是不是com.fasterxml.jackson开头的类。统一把import里的com.fasterxml.jackson替换成tools.jackson,这是Jackson 3.0包名变更造成的。同类情况也适用于部分旧版Spring API的包路径变更。
第二类是坐标不存在。Maven报“无法解析io.springfox”或者某些starter找不到,多半是旧坐标在4.0的依赖管理里已经被删除。查询Spring Boot 4的依赖管理文档,找到新坐标替换。这里我踩过坑:某个内部SDK依赖了spring-boot-starter-web,但实际上没用Spring MVC的任何能力,只是顺手引了。升级到4.0后坐标变了,我重构为直接依赖spring-boot-starter-webmvc,只保留需要的模块,反而让依赖树更干净了。
第三类是Bean定义冲突。Spring Boot 4对自动配置的校验更严格,以前模棱两可的Bean定义现在会报冲突。报错信息会告诉你哪两个@Bean方法定义的类型冲突,以及涉及的条件注解。需要你手动调整其中一个配置类的生效条件,通常是在@ConditionalOnMissingBean里明确指定Bean类型和名称。
编译期的问题修完,只是第一步。接下来把应用启动起来,运行期的报错才是硬骨头。建议启动前先把日志级别调成DEBUG,特别是spring boot autoconfigure和spring web这两个包,方便快速定位究竟是哪个自动配置环节失败。
4.4 灰度发布与回滚方案
迁移不是改完本机能跑就完事,我强烈建议你用灰度发布来降低线上风险。
比较稳妥的做法是先把新版本部署到预发环境,跑一轮核心链路回归。重点回归这几个场景:登录鉴权流程、文件上传下载(涉及Servlet 6.1的变更)、外部HTTP调用(涉及RestClient/WebClient替换)、定时任务调度、日志收集链路。这些场景最容易出现“编译能过但运行期拉胯”的问题。
然后线上灰度,可以用网关把5%流量导入新版本实例,观察两分钟metrics:错误率、响应延迟、GC情况、线程池活跃度。如果指标平稳再逐步提升流量比例至100%。回滚方案也要提前想好,最简单的方案是保留一个3.4版本的镜像不变,放大流量时新版本一旦出现CPU飙升或大量报错,立马把网关切回旧版Pod,等排查完再继续。最忌讳的是线上直接全量替换,Spring Boot 4默认禁止循环依赖、序列化行为也变了,这些差异在演练中不暴露,线上一定会加倍报给你。
5. 迁移过程常见问题与排查复盘
5.1 启动失败类问题
升级后最常见的启动失败是循环依赖异常。Spring框架从6.0起默认禁止循环依赖,Spring Boot 4延续了这个策略。以前靠三级缓存硬撑的Bean循环引用,现在启动时直接报错:The dependencies of some of the beans in the application context form a cycle。
排查思路很直接:看启动日志里循环链路的两三个Bean,把链路里的某个依赖改成@Lazy注入,或者用构造器重构成单向依赖。真正要做的是反思这个循环依赖是不是设计问题——两个Service互相调用,通常意味着它们的职责边界没划分清楚。我见过有团队试图用spring.main.allow-circular-references=true来绕过报错,救急可以,但如果是新项目,建议还是从代码结构上解决。
另外一个高频启动失败是DataSource初始化报错。Spring Boot 4对数据库连接校验更严格了,以前URL配错经常等到第一次查询才报错,现在启动阶段就会做连接检测。报错信息会直接指出是URL格式、驱动类还是账号密码问题。这种失败反而是好事——错误被提前暴露了。
5.2 序列化与HTTP调用异常
升级到Jackson 3.0后出现最多的是LocalDateTime序列化格式不一致。Jackson 3.0对Java时间类型的默认序列化格式做了一些调整,以前默认输出的可能是数组格式,现在可能变成ISO字符串格式,前后端联调的接口契约会悄然改变。
解决办法是在配置类里注册一个Jackson2ObjectMapperBuilderCustomizer,统一设置日期格式:
@Bean Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder -> { builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss"); builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); }; }HTTP调用这块,如果你从RestTemplate迁移到RestClient,注意超时配置的差异。RestTemplate里通过SimpleClientHttpRequestFactory配置连接超时和读取超时,RestClient则是基于自有的请求工厂策略。Spring Boot 4提供的自动配置能正确读取spring.http.client.factory.*配置前缀下的超时参数,不需要在代码里硬编码。迁移时直接使用自动配置的RestClient.Builder,不要自己new一个工厂,否则会错过全局的配置。
5.3 日志与可观测性配置问题
结构化日志开启后,最常见的问题是日志采集系统解析不了。很多公司内部的日志Agent还按旧的纯文本格式解析,遇到JSON格式日志,采集端解析会全部失败。如果日志收集管道的升级没跟上,先不要急着全局开启结构化日志,可以只针对部分服务开启,让日志平台先做适配。
还有一个典型误操作:开启结构化日志之后,原来logback-spring.xml里的自定义PatternLayout全部失效。这两套机制会冲突,Spring Boot 4启用structured.format配置后,自定义PatternLayout会被忽略。你需要把原来在PatternLayout里做的逻辑——比如MDC塞traceId、脱敏处理——迁移到结构化日志的框架下,通过引入自定义的日志增强模块来实现。
5.4 问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| Maven找不到spring-boot-starter-web | 坐标已改名 | 改为spring-boot-starter-webmvc |
| 编译报com.fasterxml.jackson不存在 | Jackson 3.0包名变更 | import改为tools.jackson |
| 启动报循环依赖 | Spring Boot默认禁止循环引用 | 用@Lazy或重构依赖方向 |
| LocalDateTime序列化格式不一致 | Jackson 3.0时间格式调整 | 注册ObjectMapper自定义时间格式化 |
| 自定义Starter不生效 | spring.factories被移除 | 改AutoConfiguration.imports文件 |
| 日志PatternLayout失效 | 结构化日志配置冲突 | 用logging.structured.format配置项 |
| 请求路径匹配异常 | PathPatternParser默认启用 | 检查通配符规则,明确路径层级语义 |
| URL参数绑定错误 | 配置校验更严格 | 查看启动报错,修正类型或必填项 |
| 启动报NoSuchMethodError | 残留旧版本传递依赖 | 依赖树检查并用dependencyManagement统一版本 |
| 安全路径失效 | Spring Security 7废弃API | 改用SecurityFilterChain配置,不要用WebSecurityConfigurerAdapter |
结尾:我的实际体验与建议
我从Spring Boot 4的里程碑版本就开始在内部项目里试水,前后踩了几个月坑。最大的感受是:这个版本放弃了很多“兼容上的舒适感”,换来了架构上的清爽。模块化拆分、强势的配置校验、可观测性内置、原生JSON日志,这些功能组合起来,能让一个中型Spring Boot项目的依赖树和配置结构变得前所未有的清晰。
我个人给团队的建议是:老项目别赶时髦,等Spring Cloud和核心中间件全部确认适配Spring Boot 4之后,再安排一个专门的迭代做升级。新项目如果要选技术栈,可以放心用4.0,但一定要把Starter坐标和Jackson 3.0的包名写进团队的开发规范里,否则网上找到的老教程会让新人踩半天坑。
最后再分享一个小技巧:升级到4.0之后,启动时加上--debug参数,Spring Boot会把你机器上实际生效的自动配置列表和条件判断结果全部打印出来。排查“某个自动配置为什么没生效”的时候,这一条信息比翻十篇文档都好使。希望这篇文章能帮你顺利跨过Spring Boot 4这道坎。