Boot4升后WebClient starter怎么换

Boot4升后WebClient starter怎么换

升到 Spring Boot 4 之后,不少团队会撞上同一类启动失败:业务代码里照旧注入 WebClient.Builder,结果容器里根本没有这个 bean,直接抛出 NoSuchBeanDefinitionException。或者只加了 spring-boot-starter-webmvc,却指望 RestClient、RestTemplate 的自动配置还像以前一样「跟着 Web 栈一起白送」。根因通常不是业务写法突然错了,而是 HTTP 客户端自动配置从「跟着服务端 starter 传递」改成了「显式声明客户端 starter」。

本文只讲 starter / 依赖怎么换、怎么验 。retrieve、exchange、错误处理等 API 迁移动线,见已发文 166986622(RestTemplate→RestClient 写法主文);Jackson3、Flyway、probes 等其它 Boot4 升级坑,分别见 167872166、167764600、167981493,本稿一句带过、不展开。读完你应能:对照表选对 starter、改测试侧依赖与包名、用「加/去/再加回」三步把失败钉死在缺依赖上。

现象:缺 starter,Builder 就不在了

最常见的日志形态是:

text 复制代码
NoSuchBeanDefinitionException: No qualifying bean of type
'org.springframework.web.reactive.function.client.WebClient$Builder' available

Imperative 侧也可能表现为:工程里明明有 webmvc,却发现 RestClient.Builder 没有按预期自动配置出来;或者集成测试里突然拿不到以前「默认就有」的测试客户端。升级周报里这类问题很容易被误判成「配置类写错了」「Profile 没激活」,排查半天才发现:pom 里根本没有客户端 starter。

Boot 4 的模块化策略下,仅有 Web 服务端 starter,不再等价于「客户端自动配置也齐了」 。要客户端,就显式声明客户端 starter。官方参考文档仍说明:有相应自动配置时,Boot 会创建并预配置原型 WebClient.Builder / RestClient.Builder,建议注入后再 build()。结合 Migration Guide,前提变成:先有对应的 webclient / restclient starter(或模块) ,不能指望只靠 starter-webmvc「白送」客户端自动配置。

把现象写进升级 checklist 很有用:「启动失败且堆栈点名 WebClient.Builder / 测试缺 TestRestTemplate → 先查客户端 starter,再查业务配置。」

Migration 对照表:WebClient 与 RestClient 怎么选

Spring Boot 4.0 Migration Guide「Web Client Starters」给出了清晰对照(以官方 wiki 为准,页面曾于 2026-06-28 编辑):

技术 主依赖(starter) 测试(starter)
Imperative:RestClient / RestTemplate spring-boot-starter-restclient spring-boot-starter-restclient-test
Reactive:WebClient spring-boot-starter-webclient spring-boot-starter-webclient-test

决策口诀可以压成三句:

  1. 要 Reactive WebClient → 加 spring-boot-starter-webclient
  2. 要 Imperative RestClient / RestTemplate 自动配置 → 加 spring-boot-starter-restclient
  3. client-only 场景:不要再整包拉一个 starter-webflux「只当 HTTP 客户端」;webflux starter 在 Web Starters 行的定位是反应式服务端栈,模块化后客户端应走上表显式 starter

Maven 示例(版本号跟 parent / BOM,正文只写 artifactId,勿锁死某个 patch):

xml 复制代码
<!-- Reactive:WebClient -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webclient</artifactId>
</dependency>

<!-- Imperative:RestClient / RestTemplate -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-restclient</artifactId>
</dependency>

测试侧成对出现更清晰,例如:

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webclient-test</artifactId>
  <scope>test</scope>
</dependency>

Gradle 同理,把 artifactId 换成上表对应 starter 即可。两个 starter 按实际技术选型选一个主路径,不要「两个都加以防万一」------依赖树只会更糊,排障更费时间。

非 starter 模块:一句边界

若不走 starter、只想挂模块:Migration Guide Modules 表对应 spring-boot-webclient / spring-boot-restclient(及 -test)。多数应用团队继续用 starter 更省事;模块坐标留给需要精细裁剪依赖树、或已经自管传递依赖的场景。实践上优先 starter;提模块只为边界完整。

Boot3 传递依赖 → Boot4 显式 starter

下面这张决策流把「选哪个 starter、测不测、验不验」串在一起,方便贴进内部升级文档:

记忆点只有一条:Boot4 不再把客户端自动配置绑死在「只要起了 Web」上;要哪种客户端,就声明哪种 starter。从 Boot3 迁过来时,最容易踩的坑正是「以前碰巧传递进来了,Boot4 切模块后没了,却还按老习惯排业务配置」。

业务侧怎么验:加 → 去 → 再加回

验法刻意做成可复现三步,方便写进 MR 与升级 checklist。目标不是证明「业务调用下游成功」,而是证明 Builder bean 是否由自动配置提供。

第一步:加 starter。 依赖里加入 spring-boot-starter-webclient(或 restclient),启动后注入:

java 复制代码
@Service
public class DownstreamCaller {
  private final WebClient webClient;

  public DownstreamCaller(WebClient.Builder builder) {
    this.webClient = builder.baseUrl("https://example.invalid").build();
  }
}

能正常启动、且构造注入 / @Autowired WebClient.Builder 不报缺 bean,即主路径通过。RestClient.Builder 同理,换成 spring-boot-starter-restclient。

第二步:故意去掉依赖。 从 pom / Gradle 里删掉该 starter,重启------应重新出现 NoSuchBeanDefinitionException(或等价缺 bean)。这能证明失败与 starter 缺失直接相关,而不是偶发 Profile、条件注解或自写 @Bean 冲突。

第三步:再加回。 恢复 starter,启动恢复成功。把「删依赖复现 → 加回恢复」写进 MR 描述,后续同事复查成本最低,也避免「修了一堆无关配置碰巧好了」的假象。

再次强调:这里只验证 Builder 是否由自动配置提供 。具体请求怎么写、超时怎么配、怎么从 RestTemplate 迁到 RestClient API,仍以 166986622 为准,本稿不重复,也不展开 Builder 级 timeout 配置(另文/另线处理)。

测试侧:@SpringBootTest 不再白送

Migration Guide 专节写得很直:使用 @SpringBootTest 将不再提供任何 WebClient 或 TestRestTemplate bean 。升 Boot4 后集成测试「突然没有 TestRestTemplate / WebClient」------先查依赖与注解 ,不要先怀疑业务 @Configuration。这和主工程缺 starter 是同一条模块化逻辑:测试客户端也从「注解一贴就有」变成「显式依赖 + 显式自动配置注解」。

TestRestTemplate 要加什么

按官方「TestRestTemplate Failures」口径,缺一不可:

  1. 测试依赖:org.springframework.boot:spring-boot-resttestclient
  2. 运行时还需要:org.springframework.boot:spring-boot-restclient
  3. 测试类加:@AutoConfigureTestRestTemplate
  4. 包名迁到 :org.springframework.boot.resttestclient.TestRestTemplate(从旧包迁出;@AutoConfigureTestRestTemplate 在 org.springframework.boot.resttestclient.autoconfigure)
java 复制代码
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestRestTemplate
class OrderApiIT {
  // 注入 org.springframework.boot.resttestclient.TestRestTemplate
}

编译期最容易漏的是 旧 import 没改 :IDE 可能还残留旧包路径,导致「依赖加了、注解加了,类型却解析不到」。以 4.0 API 文档包名为准即可。测试 starter 也可对照表使用 spring-boot-starter-restclient-test / spring-boot-starter-webclient-test,与主 starter 成对出现,依赖意图更清晰。

可选:RestTestClient(一句)

若团队愿意换新测试客户端,可考虑 RestTestClient + @AutoConfigureRestTestClient。这与本稿「starter 怎么换」主线无关,点到为止即可,不必扩成测试客户端选型长文。

升级周常见误判(对照表外的坑)

现场排障时,缺 starter 经常被其它噪音盖住。下面几条是周报里反复出现、却和对照表无关的误判,写出来是为了少绕路:

误判一:先改业务 @Bean。 看到 NoSuchBeanDefinitionException,有人立刻手写一个 WebClient.Builder @Bean「顶上」。短时能启动,但等于绕过 Boot 预配置的原型 Builder(编解码、消息转换器等自动装配链路也会一并绕开)。正确顺序应是:先加官方 starter,确认自动配置上了;只有在确有定制需求时,再在 已有自动配置 之上做定制,而不是用裸 Builder 顶替缺失的 starter。

误判二:把 webmvc 当万能依赖。 「主工程是 MVC,客户端也应该跟着有」在 Boot3 传递依赖较松时偶尔碰巧成立,Boot4 模块化后不再成立。webmvc 解决的是 服务端 Web ;WebClient / RestClient 自动配置要单独买单。混用 MVC 服务端 + WebClient 出站时,两边 starter 都要在依赖树里看得见。

误判三:测试绿了就以为主工程也齐了。 有的仓库测试里碰巧拉了 ...-webclient-test / resttestclient,主工程却漏了 spring-boot-starter-webclient。结果是 CI 集成测试通过、生产或本地主启动仍炸。验法必须覆盖 主 classpath :用业务 @Service 注入 Builder 做一次启动验,不要只看测试模块。

误判四:只改 test scope、忘了运行时模块。 TestRestTemplate 文档写明:除 spring-boot-resttestclient 外,还需要运行时依赖 spring-boot-restclient。只加测试坐标、漏了 restclient,会出现「注解加了仍注入失败」的假象。对照 checklist 逐项勾,比凭感觉加依赖稳。

把这四条和上一节「加 → 去 → 再加回」合在一起,升级 MR 里基本能自证:失败可复现、修复可归因、没有顺手塞无关 @Bean。

FAQ

Spring Boot 4 为什么注入 WebClient.Builder 会失败?

缺 spring-boot-starter-webclient(或模块 spring-boot-webclient)时,对应自动配置不会上,原型 WebClient.Builder bean 就不存在。堆栈点名 Builder 时,优先查依赖表,而不是先改业务 @Bean。

webclient 和 restclient 两个 starter 怎么选?

Reactive 用 webclient;Imperative 的 RestClient / RestTemplate 用 restclient。按调用栈技术选型选一个主路径;混用两套客户端时,两边 starter 都要显式声明,但那是架构选择问题,不是「随便加一个就能顶替」。

还能不能用 starter-webflux 只当 HTTP 客户端?

client-only 应显式 spring-boot-starter-webclient。webflux starter 是反应式 Web 服务端栈,不是「只要客户端」的推荐替代。Boot4 模块化的目的之一,就是把这类「整包当客户端」的模糊依赖收干净。

测试里 TestRestTemplate / WebClient 要额外加什么?

@SpringBootTest 不再白送。TestRestTemplate:@AutoConfigureTestRestTemplate + spring-boot-resttestclient + spring-boot-restclient,并改新包名。WebClient 测试侧对齐 ...-webclient-test 等对照表。漏注解或漏运行时 restclient 依赖,都会表现为「测试起不来 / 注入失败」。

小结 checklist

  • 主工程:WebClient → spring-boot-starter-webclient;RestClient/RestTemplate → spring-boot-starter-restclient
  • 测试:成对加 ...-webclient-test / ...-restclient-test(或按文档加模块坐标)
  • 集成测试:确认不再假设 @SpringBootTest 白送 WebClient / TestRestTemplate
  • TestRestTemplate:注解 + resttestclient 依赖 + 新包名 org.springframework.boot.resttestclient.TestRestTemplate
  • 验法:加 starter 能注入 Builder;去掉依赖复现失败;再加回恢复
  • 不把本文当成 RestClient API 教程;不与 probes / Jackson3 / Flyway 升级文抢主线

按表换依赖、用「删依赖复现」验一遍,这类 Boot4 启动失败通常很快闭环。升级周报贴上对照表和三步验法,比事后口头解释「怎么突然没 bean 了」高效。


相关推荐
ZealSinger5 天前
Boot4升级后MockBean和MockMvc怎么改
mockmvc·boot4·mockbean·mockitobean
ZealSinger14 天前
Spring7 RestTemplate弃用迁移
java·spring·后端开发·restclient
ZealSinger19 天前
Boot4统一http.clients配置客户端
webclient·restclient·spring boot 4·http客户端
李昊哲小课1 个月前
LLM API 协议代理 —— 从零到一全栈教程
spring boot·语言模型·大模型·openai·webclient·restclient·anthropic
魏 无羡1 个月前
webclient
java·webclient
Java牛马2 个月前
SpringBoot Starter 依赖相关总结
java·spring·springboot·starter·自动装配·依赖
AI人工智能+电脑小能手3 个月前
【大白话说Java面试题 第164题】【06_Spring篇】第24题:如何理解 SpringBoot 的 Starter?
java·自动配置·springboot·starter·自定义组件
折哥的程序人生 · 物流技术专研3 个月前
Java面试通关⑨:SpringBoot核心全集
自动配置·springboot·starter·校招·java面试·面试真题·内嵌容器
西凉的悲伤5 个月前
SpringBoot WebClient 介绍
java·spring boot·后端·webclient