SpringBoot异步调用和异常捕获
线程池配置
@Configuration
@Slf4j
@EnableAsync
public class AsyncThreadPoolConfig implements AsyncConfigurer {
@Bean(name = "asyncExecutor")
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(20);
// 线程池最大线程数
executor.setMaxPoolSize(60);
// 线程队列最大线程数
executor.setQueueCapacity(100);
// 线程池中线程最大空闲存活时间
executor.setKeepAliveSeconds(60);
//核心线程是否允许超时,默认:false
executor.setAllowCoreThreadTimeOut(false);
// 线程名称前缀
executor.setThreadNamePrefix("AsyncThread_");
// IOC容器关闭时是否阻塞等待剩余的任务执行完成,默认:false(true则必须设置setAwaitTerminationSeconds)
executor.setWaitForTasksToCompleteOnShutdown(true);
// 阻塞IOC容器关闭的时间
executor.setAwaitTerminationSeconds(60);
executor.setRejectedExecutionHandler(
new ThreadPoolExecutor.CallerRunsPolicy()
);
executor.initialize();
return executor;
}
/**
* 异常捕获
*
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
@SuppressWarnings("all")
class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.error("AsyncError: {}, Method: {}, Param: {}, Error: {}",
throwable.getMessage(), method.getName(),
JSON.toJSONString(objects), throwable);
// 捕获异常后进行进一步的处理
}
}
}
实际应用
@Async("asyncExecutor")
@Override
public void print(Integer num) {
if (num.equals(20)) {
int i = 1 / 0;
}
System.out.println("AsyncExecutor: " + num);
}
从测试结果可以看出,异步打印而且成功捕获了异常