Spring 异步任务的创建、自定义配置和原理

栏目: Java · 发布时间: 5年前

内容简介:当我们调用默认情况下,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);
        }
    }
     
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

注意力商人

注意力商人

吳修銘 / 黃庭敏 / 天下雜誌 / 2018-4-2 / NT$650

電子郵件,免費!照片分享,無上限! 你是否想過,隨手可得的免費內容、便利的免費服務,到底都是誰在付費? 如果商品免費,那你就不是消費者,而是商品! 你我可能都不知不覺地把自己賣給了注意力商人! 「『媒體轉型、網路演化與資訊浪潮」此一主題最具洞見的作者。』──黃哲斌(資深媒體人) 「這是少有的關注產業發展的傳播史,對現在或未來的『注意力產業』」中人來說,不可不讀。」──......一起来看看 《注意力商人》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器