Java 如何在Spring的@Async方法中使用当前区域设置

Java 如何在Spring的@Async方法中使用当前区域设置,java,spring,localization,Java,Spring,Localization,我有一个服务,它有异步发送电子邮件的方法。发送方方法有一个@Async注释。但当我尝试在该方法中使用当前语言环境时,它总是默认的。所以问题是如何将区域设置传递给@Async方法。可以实现自定义AsyncTaskExecutor,它将区域设置作为参数。然后,它将为其上下文设置一个区域设置 public interface LocaleAsyncTaskExecutor extends AsyncTaskExecutor { void execute(Runnable task, Local

我有一个服务,它有异步发送电子邮件的方法。发送方方法有一个
@Async
注释。但当我尝试在该方法中使用当前语言环境时,它总是默认的。所以问题是如何将区域设置传递给
@Async
方法。

可以实现自定义
AsyncTaskExecutor
,它将区域设置作为参数。然后,它将为其上下文设置一个区域设置

public interface LocaleAsyncTaskExecutor extends AsyncTaskExecutor {
    void execute(Runnable task, Locale locale);
}

我相信您正在使用LocaleContextHolder访问当前的语言环境

在执行异步方法之前,将当前区域设置设置为LocaleContextHolder,可继承标志设置为true,例如:

Locale currentLocale = LocaleContextHolder.getLocale();
LocaleContextHolder.setLocale(currentLocale, true);
当inheritable标志设置为true时,LocaleContext将由当前线程生成的任何子线程继承,其行为类似于本地线程


参考资料:

chunhoong的解决方案对我来说很有效,但它并不是那么有意义。 对我来说,有一个更好的解决方案:为所有线程设置相同的请求上下文。主线程和所有@Async线程应共享DispatcherServlet上下文(setThreadContextInheritable(true))。它就像一个符咒:

@SpringBootApplication
public class CoreApplication {
    public static void main(String[] args) {
        SpringApplication
                .run(CoreApplication.class, args)
                .getBean(DispatcherServlet.class)
                .setThreadContextInheritable(true);
    }
}

PS:这对我帮助很大:

只需将其传递到方法中。你能分享你的示例代码吗?@M.Deinum是否有比在每个方法中传递区域设置更通用、更优雅的解决方案?@pleft抱歉,有一种复杂的逻辑围绕着它不是真的。。。它在不同的线程中运行,因此使用
LocaleContextHolder
不是一个选项,因为它基于
ThreadLocal
(这也是为什么您得到的是默认的
Locale
,而不是您期望的)。