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