- Java's asynchronous processing of Thread/Runnable, Callable/Future
- Asynchronous processing of Servlet 2.5 Tomcat's CometProcessor, Jetty's Continuations
- Asynchronous processing of Servlet 3.0 asyncSupported, AsyncContext
- Asynchronous processing of Spring MVC @Async, AsyncTaskExecutor
- Spring MVC的SSE ResponseBodyEmitter、SseEmitter、StreamingResponseBody
Spring Boot itself has not changed much for asynchronous calls, and it is basically Spring MVC's @Async.
(1) Turn on Spring's asynchronous support
@Configuration @EnableAsync public class SpringAsyncConfig { }
Asynchronous processing is also automatically enabled when @EnableWebMvc is enabled, but @EnableWebMvc cannot be used in Spring Boot projects. It disables part of Spring Boot's AutoConfigure functionality.
There are instructions in the official documentation:
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration
@EnableWebMvc @ComponentScan("com.example.component") @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { configure.setTaskExecutor (mvcAsyncExecutor ()); } @Bean public AsyncTaskExecutor mvcAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(10); return executor; } }
(2) Define a method that needs to perform asynchronous processing
1) No return value
@Async public void asyncMethodWithVoidReturnType() { System.out.println("Execute method asynchronously. " + Thread.currentThread().getName()); }
2) with return value
@Async public Future<String> asyncMethodWithReturnType() { System.out.println("Execute method asynchronously - " + Thread.currentThread().getName()); try { Thread.sleep(5000); return new AsyncResult<String>("hello world !"); } catch (InterruptedException e) { } return null; }
(3) Definition of asynchronous thread pool
1) A thread pool
@Configuration @EnableAsync public class SpringAsyncConfig { @Bean public AsyncTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(10); return executor; } }
2) Multiple thread pools
@Configuration @EnableAsync public class SpringAsyncConfig { @Bean(name = "threadPoolTaskExecutor1") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } @Bean(name = "threadPoolTaskExecutor2") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } }
@Async("threadPoolTaskExecutor1") public void asyncMethodWithConfiguredExecutor() { System.out.println("Execute method with configured executor - " + Thread.currentThread().getName()); }
(4) Handling of asynchronous exceptions
public interface AsyncConfigurer { Executor getAsyncExecutor(); AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(); }
AsyncConfigurerSupport is an implementation of the AsyncConfigurer interface but does nothing in it.
@Configuration @EnableAsync class SpringAsyncConfigurer extends AsyncConfigurerSupport { @Bean public ThreadPoolTaskExecutor asyncExecutor() { ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); threadPool.setCorePoolSize(3); threadPool.setMaxPoolSize(3); threadPool.setWaitForTasksToCompleteOnShutdown(true); threadPool.setAwaitTerminationSeconds(60 * 15); return threadPool; } @Override public Executor getAsyncExecutor() { return asyncExecutor; } }
You can implement the AsyncConfigurer interface yourself to handle exceptions.
@Configuration @EnableAsync public class SpringAsyncConfigurer implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { return new ThreadPoolTaskExecutor(); } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new CustomAsyncExceptionHandler(); } }
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { System.out.println("Exception message - " + throwable.getMessage()); System.out.println("Method name - " + method.getName()); for (Object param : obj) { System.out.println("Parameter value - " + param); } } }
Reference:
http://qiita.com/kazuki43zoo/items/8be79f98621f90865b78
http://qiita.com/kazuki43zoo/items/ce88dea403c596249e8a
http://qiita.com/kazuki43zoo/items/53b79fe91c41cc5c2e59