Spring 中的本地化问题与新线程上的 Rx java

Localization issue in Spring with Rx java on new thread

我正在尝试使 RxJava 适应现有的 Spring 项目。我的目标是异步提供 WS REST 调用(我知道 @Async,但让我们忽略这一点)。

问题在于通过 REST 调用提供的语言环境进行的翻译。在请求中,我有一个 header 这样的

Accept-Language: cs

表明我想以所需的语言提供服务。现在 RxJava 开始了。我创建了一个 Observable,它从数据库中获取行,并通过 Observable.map 操作使用

进行翻译
LocaleContextHolder.getLocale().getLanguage();

问题是,如 Spring LocaleContextHolder 规范所述:

Simple holder class that associates a LocaleContext instance with the **current** **thread**. 

但是我对 Observable 的订阅在新线程池中工作,因为这是一项成本高昂的操作。所以我的简化订阅看起来像这样:

@RequestMapping(value = "/valid", method = RequestMethod.GET)
@ResponseBody
public DeferredResult<List<CustomerServicesPrintableInfo>> getValidServicesForCustomer() {
    DeferredResult<List<CustomerServicesPrintableInfo>> result = new DeferredResult<>(10000L);
    List<CustomerServicesPrintableInfo> customerServices = new ArrayList<>();
    customerServiceService.getPrintableByCustomerLogin(username)
            .subscribeOn(Schedulers.io())
            .subscribe(customerServices::add,
                    LOGGER::error,
                    () -> {
                        result.setResult(customerServices);
                    });

    return result;

但问题是一旦执行在新线程中运行,新线程中的区域设置是默认的 eng 而不是我想要的 cs。如果我忽略 .subscribeOn(Schedulers.io()),一切正常,但在当前线程上,这是不可取的。

所以问题是 - 我如何清楚地传播(或告诉 Spring/RxJava)新创建的线程应使用传入语言环境?

你要做的是将当前线程关联到LocaleContext;最简单的方法是创建自己的调度程序,这些调度程序知道他们需要将它传递给新线程,并在它们开始执行时 set/reset 它。