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 了」高效。


相关推荐
ZealSinger2 天前
Boot4升后Spring Retry依赖怎么管
依赖管理·boot4·升级踩坑·springretry
ZealSinger4 天前
Boot4升后AMQP retry属性怎么改
amqp·boot4·升级踩坑·rabbitretry
ZealSinger10 天前
Boot4升后Kafka retry属性怎么改
kafka·retry·boot4·升级踩坑
ZealSinger11 天前
Boot4升后session_redis属性怎么改名
redis·springsession·boot4·升级踩坑
yz_aiks13 天前
RestTemplate 废弃后迁移 RestClient 实战:Spring Boot 4.2 升级指南
java·spring boot·后端·微服务·restclient
ZealSinger16 天前
Boot4升后HttpServiceClient怎么换
boot4·httpservice·importhttp·升级踩坑
ZealSinger25 天前
Boot4升级后MockBean和MockMvc怎么改
mockmvc·boot4·mockbean·mockitobean
ZealSinger1 个月前
Spring7 RestTemplate弃用迁移
java·spring·后端开发·restclient
ZealSinger1 个月前
Boot4统一http.clients配置客户端
webclient·restclient·spring boot 4·http客户端