请参考文档:https://rensanning.iteye.com/blog/2360749
参考:
http://qiita.com/kazuki43zoo/items/8be79f98621f90865b78
http://qiita.com/kazuki43zoo/items/ce88dea403c596249e8a
http://qiita.com/kazuki43zoo/items/53b79fe91c41cc5c2e59
异步处理
- Java的异步处理Thread/Runnable、Callable/Future
- Servlet 2.5的异步处理 Tomcat的CometProcessor、Jetty的Continuations
- Servlet 3.0的异步处理 asyncSupported、AsyncContext
- Spring MVC的异步处理 @Async、AsyncTaskExecutor
- Spring MVC的SSE ResponseBodyEmitter、SseEmitter、StreamingResponseBody
- Spring Boot本身对异步调用没有多大的变动,基本还是Spring MVC的@Async。
(1)开启Spring的异步支持 (添加@EnableAsync)
@Configuration @EnableAsync public class SpringAsyncConfig{ }
开启@EnableWebMvc的时候也自动开启了异步处理,但在Spring Boot项目中是不能使用@EnableWebMvc的。它会使Spring Boot的AutoConfigure一部分功能失效。
官方文档里有说明:
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration
//可以不配置 @ComponentScan("com.sea.test") @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter {
//配置异步的支持 @Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { configurer.setTaskExecutor(mvcAsyncExecutor()); }
//异步线程池的定义 @Bean public AsyncTaskExecutor mvcAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(10); return executor; } }
(2)定义需要执行异步处理的方法
1)没有返回值
@Async public void asyncMethodWithVoidReturnType() { System.out.println("Execute method asynchronously. " + Thread.currentThread().getName()); }
2)带返回值
@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)异步线程池的定义
1)一个线程池
@Configuration @EnableAsync public class SpringAsyncConfig { @Bean public AsyncTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(10); return executor; } }
2)多个线程池
@Configuration @EnableAsync public class SpringAsyncConfig { @Bean(name = "threadPoolTaskExecutor1") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } @Bean(name = "threadPoolTaskExecutor2") public Executor threadPoolTaskExecutor() { return new ThreadPoolTaskExecutor(); } }
3) 多个线程池指定使用哪一个:
@Async("threadPoolTaskExecutor1") public void asyncMethodWithConfiguredExecutor() { System.out.println("Execute method with configured executor - " + Thread.currentThread().getName()); }
(4)异步异常的处理
public interface AsyncConfigurer { Executor getAsyncExecutor(); AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(); }
AsyncConfigurerSupport是AsyncConfigurer接口的实现但里边什么也没做。
@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; } }
可以自己实现AsyncConfigurer接口处理异常。
@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); } } }