响应式编程模型(如 Spring WebFlux)和传统的 Servlet 基于线程的模型(如 Spring MVC)在处理请求的方式上有显著不同。在响应式编程中,操作是异步非阻塞的,并且是基于事件循环的。这意味着请求处理不再是由单个线程从头到尾负责,而是可以在多个线程之间切换。
ThreadLocal
是 Java 提供的一种线程封闭机制,它允许存储线程级别的数据。在传统的 Spring MVC 应用中,每个请求都是由一个固定的线程处理的,因此可以便利地使用 ThreadLocal
来存储和访问与请求相关的数据,如用户凭证、跟踪标识符等。
然而,在响应式编程模型中,因为处理流程可能在多个线程之间切换,所以无法保证整个请求处理链在同一个线程中执行。由于 ThreadLocal
的数据是绑定到特定线程的,当请求处理跳转到新的线程时,原线程的 ThreadLocal
中存储的数据将不再可用。这会导致在新的线程上下文中无法获取之前线程的 ThreadLocal
数据,因而无法保证跨线程的数据一致性。
Spring WebFlux 的响应式编程模型使用了 Project Reactor,它提供了一个 Context
API 来存储上下文相关的数据,这个 API 是为了解决在响应式流操作中传递数据的问题。Context
是跟随响应式流的,并且可以在响应式链中的不同操作和不同线程间保持数据的连贯性。
为了在响应式环境中传递类似 ThreadLocal
的数据,你应该使用 Reactor 的 Context
,而不是 ThreadLocal
。