之前使用了@Async注解,子线程无法获取到上下文信息,导致流量无法打到灰度,然后改成 线程池的方式,每次调用异步调用的时候都手动透传 上下文(硬编码)解决了问题。
后面查阅了资料,找到了方案不用每次硬编码,来上下文透传数据了。
方案一:
继承线程池,重写相应的方法,透传上下文。
方案二:(推荐)
线程池ThreadPoolTaskExecutor,有一个TaskDecorator装饰器,实现这个接口,透传上下文。
方案一:继承线程池,重写相应的方法,透传上下文。
1、ThreadPoolTaskExecutor spring封装的线程池
ThreadPoolTaskExecutor 线程池代码如下:
https://www.jianshu.com/p/2a58e1df2bbb
@Bean(ExecutorConstant.simpleExecutor_3)
public Executor asyncExecutor3() {
MyThreadPoolTaskExecutor taskExecutor = new MyThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(corePoolSize);
taskExecutor.setMaxPoolSize(maxPoolSize);
taskExecutor.setQueueCapacity(queueCapacity);
taskExecutor.setThreadNamePrefix(threadNamePrefix_3);
taskExecutor.initialize();
return taskExecutor;
}
//------- 继承父类 重写对应的方法 start
class MyCallable<T> implements Callable<T> {
private Callable<T> task;
private RequestAttributes context;
public MyCallable(Callable<T> task, RequestAttributes context) {
this.task = task;
this.context = context;
}
@Override
public T call() throws Exception {
if (context != null) {
RequestContextHolder.setRequestAttributes(context);
}
try {
return task.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor{
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(new MyCallable(task, RequestContextHolder.currentRequestAttributes()));
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(new MyCallable(task, RequestContextHolder.currentRequestAttributes()));
}
}
//------- 继承父类 重写对应的方法 end
1、MyCallable是继承Callable,创建MyCallable对象的时候已经把Attributes对象赋值给属性context了(创建MyCallable对象的时候因为实在当前主线程创建的,所以是能获取到请求的Attributes),在执行call方法前,先执行了RequestContextHol