图解Reactor Context的‘作用域’:搞懂Spring WebFlux上下文传递的5个关键场景
在响应式编程的世界里,数据流的异步特性让传统的线程局部变量(ThreadLocal)彻底失效。想象一下,当你的请求像接力棒一样在多个线程间传递时,如何确保关键信息不丢失?这就是Reactor Context的用武之地——它像一条隐形的数据隧道,贯穿整个响应式调用链。
但Context有个反直觉的特性:它只对上游操作可见。这个设计让许多开发者踩坑:明明设置了值,为什么下游读不到?为什么不同操作符里的Context表现不一致?本文将用五个真实场景,配合流程图解,帮你建立清晰的Context心智模型。
1. 跨服务追踪:TraceId的传递迷宫
微服务架构下,一个请求往往需要跨越多个服务。在同步调用中,我们习惯用ThreadLocal携带TraceId。但在WebFlux的异步世界里,这个模式彻底失效。来看一个典型场景:
code复制A服务 → B服务 → C服务
假设每个服务都会添加自己的日志标记,我们需要保证整个调用链使用同一个TraceId。正确的Context操作应该是:
java复制// 在A服务的WebFilter中初始化TraceId
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String traceId = UUID.randomUUID().toString();
return chain.filter(exchange)
.contextWrite(ctx -> ctx.put("traceId", traceId));
}
// B服务调用C服务时
public Mono<Response> callServiceC() {
return Mono.deferContextual(ctx -> {
String traceId = ctx.get("traceId");
return webClient.post()
.header("X-Trace-Id", traceId)
