问题
spring里面可以使用ThreadLocal在同一请求里隐式传递数据。
但在Vert.x里,由于是采用Eventloop来异步处理请求,同一个线程会处理许多的请求,使用ThreadLocal来传递数据会导致数据错乱。那么有什么方法可以实现这一要求呢?
context分析
Vert.x里存在一个Context的核心接口
/**
执行的 Handler 执行上下文。
当 Vert.x 向处理程序提供事件或调用 的 start 或 stop 方法 Verticle时,执行与 Context.
通常,上下文是*事件循环上下文*,并且绑定到特定的事件循环线程。因此,该上下文的执行始终发生在完全相同的事件循环线程上。
在工作线程顶点和运行内联阻塞代码的情况下,工作线程上下文将与执行相关联,该执行将使用工作线程池中的线程。
当处理程序由与特定上下文关联的线程设置时,Vert.x 将保证在执行该处理程序时,该执行将与同一上下文相关联。
如果处理程序由与上下文无关的线程(即非 Vert.x 线程)设置。然后,将为该处理程序创建一个新上下文。
换言之,上下文是传播的。
这意味着,当部署顶点时,它设置的任何处理程序都将与相同的上下文相关联 - 顶点的上下文。
这意味着(在标准顶点的情况下)顶点代码将始终使用完全相同的线程执行,因此您不必担心多线程访问顶点状态,并且可以将应用程序编码为单线程。
此类还允许任意数据 put 在上下文中, get 因此可以很容易地在不同的处理程序之间共享,例如,顶点实例。
此类还提供 runOnContext 允许使用相同上下文异步执行操作的功能。
*/
public interface Context {
<T> T get(Object key);
void put(Object key, Object value);
boolean remove(Object key);
<T> T getLocal(Object key);
/**
* Put some local data in the context.
* <p>
* This can be used to share data between different handlers that share a context
*
* @param key the key of the data
* @param value the data
*/
void putLocal(Object key, Object value);
boolean removeLocal(Object key);
}
大约 5 分钟