- 上下文丢失主要是因为主线程和子线程的上下文不能共享。
- 可以通过执行异步任务之前,将主线程上的上下文信息拷贝到子线程上。
通过自定义 TaskDecorator 来拷贝主线程上的上下文信息到子线程,然后将自定义的 TaskDecorator实现类 设置到线程池上。
@Configuration
public class ThreadPoolConfig {@Bean(name = "customizeTaskExecutor")public ThreadPoolTaskExecutor threadPoolTaskExecutor(){ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor();// 核心线程数=cpu核心数+1poolExecutor.setCorePoolSize(5);// 最大线程数=cpu核心数*2poolExecutor.setMaxPoolSize(8);// 设置任务装饰器poolExecutor.setTaskDecorator(taskDecorator());// 任务被拒绝后,交给调用线程执行poolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return poolExecutor;}@Beanpublic TaskDecorator taskDecorator(){return new TaskDecorator() {@Overridepublic Runnable decorate(Runnable runnable) {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();return ()->{try {RequestContextHolder.setRequestAttributes(requestAttributes);runnable.run();}finally {RequestContextHolder.resetRequestAttributes();}};}};}
}