Could someone please tell me the difference between getAsyncExecutor
and threadPoolTaskScheduler
, as explained in the spring async-instrumentation document?
I created the config below, as mentioned in the above doc.
@Configuration
public class ServiceConfig {
@Configuration(proxyBeanMethods = false)
@EnableAsync
static class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return ContextExecutorService.wrap(
Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("my-sad-thread-%d").build()), ContextSnapshot::captureAll);
}
}
@Bean(name = "taskExecutor", destroyMethod = "shutdown")
ThreadPoolTaskScheduler threadPoolTaskScheduler() {
final ThreadPoolTaskScheduler threadPoolTaskScheduler =
new ThreadPoolTaskScheduler() {
@Override
protected ExecutorService initializeExecutor(
final ThreadFactory threadFactory,
final RejectedExecutionHandler rejectedExecutionHandler) {
final ExecutorService executorService =
super.initializeExecutor(threadFactory, rejectedExecutionHandler);
return ContextExecutorService.wrap(executorService, ContextSnapshot::captureAll);
}
@Override
public ScheduledExecutorService getScheduledExecutor() throws IllegalStateException {
return ContextScheduledExecutorService.wrap(super.getScheduledExecutor());
}
};
threadPoolTaskScheduler.setThreadNamePrefix("SpTaskExecutor1");
threadPoolTaskScheduler.initialize();
return threadPoolTaskScheduler;
}
@Bean
public WebMvcConfigurer webMvcConfigurerConfigurer(final AsyncTaskExecutor taskExecutor) {
return new WebMvcConfigurer() {
@Override
public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
configurer.setTaskExecutor(taskExecutor);
// Added timeout of 60 seconds for async api due to downloads api having 100K rows.
configurer.setDefaultTimeout(60 * 1000L /* 60 sec*/);
}
};
}
}
I have a simple Hello World
controller.
public class HelloWorldController {
@GetMapping("/hello")
public ResponseEntity<StreamingResponseBody> sendGreetings() {
logMsg("Hello Outside Body Thread");
return ResponseEntity.ok()
.body(
outputStream ->
{
logMsg("Hello Inside Body Thread");
outputStream.write("Hello World".getBytes());
}
);
}
@GetMapping("/hello1")
public ResponseEntity<String> sendGreetings1() {
logMsg("Hello1");
return ResponseEntity.ok().body("Hello World");
}
private void logMsg(final String msg) {
log.info("Thread: {} {}", Thread.currentThread().getName(), msg);
}
}
I am observing logs like the one below.
2024-09-02T16:04:56.072+05:30 INFO 68014 --- [nio-8080-exec-5] c.e.h.controller.HelloWorldController : Thread: http-nio-8080-exec-5 Hello Outside Body Thread
2024-09-02T16:04:56.072+05:30 INFO 68014 --- [pTaskExecutor11] c.e.h.controller.HelloWorldController : Thread: SpTaskExecutor11 Hello Inside Body Thread
2024-09-02T12:35:17.273+05:30 INFO 21749 --- [nio-8080-exec-4] c.e.h.controller.HelloWorldController : Thread: http-nio-8080-exec-4 Hello1
threadPoolTaskScheduler
is being used. Where is getAsyncExecutor
expected to be used?
The sample code is placed here
getAsyncExecutor()
- is used when you invoke methods annotated with @Async
.
ThreadPoolTaskScheduler
- is used for scheduling tasks (like @Scheduled
annotation) or for asynchronous request handling like with StreamingResponseBody