@Configuration
@EnableAsync
public class ListenerAsyncConfiguration implements AsyncConfigurer {
private static final Logger log = Logger.getLogger(ListenerAsyncConfiguration.class);
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);
taskExecutor.setMaxPoolSize(500);
taskExecutor.setQueueCapacity(100000);
taskExecutor.setThreadNamePrefix("task-async");
taskExecutor.setTaskDecorator(new AsyncTaskContextDecorator());
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
static class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info("Exception message - " + throwable.getMessage());
log.info("Method name - " + method.getName());
for (Object param : obj) {
log.info("Parameter value - " + param);
}
}
}
}
public class AsyncTaskContextDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
Map<String, Object> container = CurrentContext.getContainer();
try {
return () -> {
try {
CurrentContext.setContainer(container);
RequestContextHolder.setRequestAttributes(attributes);
runnable.run();
} finally {
RequestContextHolder.resetRequestAttributes();
CurrentContext.clear();
}
};
} catch (Exception e) {
return runnable;
}
}
}