我知道每个请求都由一个 servlet 线程提供服务,但是一个用户会话是否可以由两个不同的线程提供两个请求?
如果上述情况真的发生,那么第一个请求服务线程存储的线程局部变量被第二个请求服务线程读取怎么办?
恐怕如果我将用户凭据存储在第一个线程的 Spring Security 的 SecurityContextHolder(它使用线程局部变量)中,第二个线程将无法访问用户凭据......
我知道每个请求都由一个 servlet 线程提供服务,但是一个用户会话是否可以由两个不同的线程提供两个请求?
如果上述情况真的发生,那么第一个请求服务线程存储的线程局部变量被第二个请求服务线程读取怎么办?
恐怕如果我将用户凭据存储在第一个线程的 Spring Security 的 SecurityContextHolder(它使用线程局部变量)中,第二个线程将无法访问用户凭据......
不,一个请求不会由多个线程处理。真正可能发生的是一个线程处理 2 个请求。这就是您自己使用线程局部变量时应该非常小心的原因。但是您可以信任 Spring 框架:它做的事情是正确的。例如,在使用线程本地时可以使用会话或请求 ID,因此不会混淆由一个线程处理的 2 个请求。
我知道每个请求都由一个 servlet 线程提供服务,但是一个用户会话是否可以由两个不同的线程提供两个请求?
是的,这是可能的。
恐怕如果我将用户凭据存储在第一个线程的 Spring Security 的 SecurityContextHolder(它使用线程局部变量)中,第二个线程将无法访问用户凭据......
Spring 为每个请求单独建立安全性,您不必自己处理。
同一用户的两个单独请求(很可能)由两个不同的线程处理。
我不确定 Spring 做了什么,但 Servlet api 提供了一种检索特定于用户会话的数据的方法(服务器如何跟踪会话无关紧要,但看看 cookie 和 url 重写)。
现在,如果我想在 threadlocal 变量上拥有用户凭据(这并不罕见,因为 ThreadLocal 伪单例是我所知道的最方便的注入方式),我会将它们存储在用户 HttpSession 上(这是持久的同一用户的所有请求)并使用 servlet 过滤器在每个请求开始时将它们放在 threadlocal 上。
我希望这能让你更清楚一些。我发现即使使用最新的框架,也最好了解幕后发生的事情:)