这是我基于
https://dev59.com/62Ag5IYBdhLWcg3wU5gS#33337838的工作解决方案。
AsyncContextAwarePoolExecutor.java
public class AsyncContextAwarePoolExecutor extends ThreadPoolTaskExecutor {
public static final String BEAN_NAME = "AsyncPoolExecutor";
private static class ContextAwareCallable<T> implements Callable<T> {
private Callable<T> task;
private RequestAttributes context;
public ContextAwareCallable(Callable<T> task, RequestAttributes context) {
this.context = context;
this.task = task;
}
@Override
public T call() throws Exception {
if (null != context) {
RequestContextHolder.setRequestAttributes(context);
}
try {
return task.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
private <T> ContextAwareCallable getContextAwareCallable(Callable<T> task) {
return new ContextAwareCallable(
task,
RequestContextHolder.currentRequestAttributes()
);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(
getContextAwareCallable(task)
);
}
@Override
public <T> CompletableFuture<T> submitCompletable(Callable<T> task) {
return super.submitCompletable(
getContextAwareCallable(task)
);
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(
getContextAwareCallable(task)
);
}
}
AsyncExceptionHandler.java
@Slf4j
public final class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... params) {
log.error(
throwable.getMessage(),
throwable
);
}
}
AsyncConfiguration.java
@Configuration
@EnableAsync
public abstract class AsyncConfiguration implements AsyncConfigurer {
@Autowired
private AsyncSettings asyncSettings;
@Override
public Executor getAsyncExecutor() {
AsyncSettings.Thread.Prefix prefix = asyncSettings.getThread().getPrefix();
AsyncSettings.Pool.Size size = asyncSettings.getPool().getSize();
AsyncContextAwarePoolExecutor executor = new AsyncContextAwarePoolExecutor();
executor.setBeanName(AsyncContextAwarePoolExecutor.BEAN_NAME);
executor.setCorePoolSize(size.getCore());
executor.setMaxPoolSize(size.getMax());
executor.setQueueCapacity(asyncSettings.getQueue().getCapacity());
executor.setThreadGroupName(prefix.getGroup());
executor.setThreadNamePrefix(prefix.getThread());
executor.initialize();
return executor;
}
@Bean(AsyncContextAwarePoolExecutor.BEAN_NAME)
public Executor getAsyncExecutorBean() {
return getAsyncExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}
SpringBoot 控制器
@Autowired
private DefaultApiLogic defaultApiLogic;
@Async(AsyncContextAwarePoolExecutor.BEAN_NAME)
public CompletableFuture<ResponseEntity<Version>> getVersion() {
String requestBaseUrl;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
requestBaseUrl = request.getRequestURL().toString();
} else {
requestBaseUrl = null;
}
return CompletableFuture.supplyAsync(
() -> ResponseEntity.ok(
defaultApiLogic.getVersion(requestBaseUrl)
),
Runnable::run
);
}