【问题标题】:Is LocaleContextHolder safe in service layerLocaleContextHolder 在服务层中是否安全
【发布时间】:2013-09-09 17:45:36
【问题描述】:

根据官方文档,LocaleContextHolder 是:

将 LocaleContext 实例与当前线程相关联的简单持有者类。

所以它与当前的thread 相关联,但这是在谈论Thread 线程还是当前请求的线程。

抱歉,如果这是一个愚蠢的问题,我不是 LocaleContextHolder 不绑定到 HTTP 会话或其他东西,因此它可以安全地用于任何服务层类。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    如果您查看LocaleContextHolder 的源代码,您会注意到它有一个ThreadLocal 变量(实际上有两个)

    private static final ThreadLocal<LocaleContext> localeContextHolder =
            new NamedThreadLocal<LocaleContext>("Locale context");
    

    您可以阅读ThreadLocal 是什么,但为了我们的利益,将其视为一种数据结构,将当前执行线程的 ID 映射到其泛型类型的对象,LocaleContext 这里。

    Servlet 容器有一个线程池,用于处理客户端请求。当一个请求进来时,它会提取其中一个线程并执行你的 servlet 的service() 方法。使用 Spring,这会导致 DispatcherServlet 执行并调用您的 @Controller 的处理程序方法。这一切都发生在 servlet 容器选择的原始 Thread 中。

    所以当你的 @Service 类的方法被调用时,你仍然在同一个线程中。

    LocaleContextHolder 中的 ThreadLocal 在请求处理早期的某个时间点是 set(),在 FrameworkServlet(它是 DispatcherServlet 的父类型)方法 initContextHolders() 中由 processRequest() 调用doGet()doPost() 等方法。 Locale 是从 HttpServletRequest 及其 getLocale() 方法构建的。

    【讨论】:

    • 很好的解释,节省我大量阅读以获得这样的精髓。还有一个问题是,由于容器拥有一个线程池,每个线程一个localeContextHolder,这是否意味着每个thread 支持一个DispatchServlet,每个dispatchServet 拥有一个localeContexHolder?提前致谢。
    • @Dreamer 不完全是。每个线程都会有一个LocaleContext(如果它是set() 上的ThreadLocal)。 servlet 容器产生的Thread 有一个run() 方法,该方法引用了您的DispatcherServlet,它使用HttpServletRequestHttpServletREsponse 对象调用方法。 DispatcherServlet 分派 到您的@Controller 方法。 localeContexHolderLocaleContexHolder 类的 static 字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    相关资源
    最近更新 更多