内容简介:当我们调用默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一
@EnableAsync
和 @Configuration
类一起使用,如下所示,为整个Spring应用程序上下文启用注释驱动的异步处理
@Configuration
@EnableAsync
public class AppConfig {
}
复制代码
2.2 编写异步任务
@Component
public class EmailService {
@Async
//无返回类型
public void send(String from, String to, String subject, String text) {
//do send
}
@Async
//有返回类型
public Future<String> send(String from, String to, String subject, String text) {
System.out.println("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
}
复制代码
当我们调用 send()
方法时,这个任务就会异步去执行,
@Async
不仅可以用在方法上,还可以用在Bean类上,如果在类所有方法都是异步的
3 自定义Executor
默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一 TaskExecutor bean
,或者另一个名为“taskExecutor”的 Executor bean
。如果两者都不可解析,则将使用 SimpleAsyncTaskExecutor
处理异步方法调用。此外,具有 void
返回类型的带注解的方法不能将任何异常发送回调用者。默认情况下,仅记录下此类未捕获的异常。
要自定义所有这些,需要实现 AsyncConfigurer
并提供:
-
自定义
Executor: 通过getAsyncExecutor()方法实现 -
自定义
AsyncUncaughtExceptionHandler: 通过getAsyncUncaughtExceptionHandler()来实现
注意: AsyncConfigurer
配置类在应用程序上下文引导程序的早期初始化。如果你对其他 bean
有任何依赖,请确保尽可能地声明它们为 Lazy
,以便让它们通过其他后处理器。
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.setWaitForTasksToCompleteOnShutdown(true);//默认是false,即shutdown时会立即停止并终止当前正在执行任务
executor.setRejectedExecutionHandler((r, executor1) -> {
for(;;) {
try {
executor1.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
});//指定被拒绝任务的处理方法,经过测试当并发量超过队列长度时可以继续执行,否则会抛出 org.springframework.core.task.TaskRejectedException异常
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();//自定义未捕获异常处理,参考 4 异常处理 小节
}
}
复制代码
3.1 在方法级别自定义Executor
以上为应用级别重写Executor,Spring还提供方法级别重写: 开启Async并自定义Executor:
@Configuration
@EnableAsync
public class SpringAsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
}
复制代码
使用自定义Executor
@Async("threadPoolTaskExecutor")
public void asyncMethodWithConfiguredExecutor() {
System.out.println("Execute method with configured executor - "
+ Thread.currentThread().getName());
}
复制代码
4 异常处理
当方法返回类型是 Future
时,异常处理很容易 - Future.get()方法将抛出异常。
但是,如果返回类型为void,则异常不会传播到调用线程。因此,我们需要添加额外的配置来处理异常。
我们将通过实现 AsyncUncaughtExceptionHandler
接口来创建自定义异步异常处理程序。当存在任何未捕获的异步异常时,将调用 handleUncaughtException()
方法:
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);
}
}
}
复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Flink 维表关联系列之自定义异步查询
- SpringBoot | :异步开发之异步调用
- 改进异步封装:处理带返回值的异步调用
- 异步发展流程 —— Generators + co 让异步更优雅
- 文件系统与异步操作——异步IO那些破事
- js异步从入门到放弃(四)- Generator 封装异步任务
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Uberland
Alex Rosenblat / University of California Press / 2018-11-19 / GBP 21.00
Silicon Valley technology is transforming the way we work, and Uber is leading the charge. An American startup that promised to deliver entrepreneurship for the masses through its technology, Uber ins......一起来看看 《Uberland》 这本书的介绍吧!