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

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

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

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

查看所有标签

猜你喜欢:

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

锋利的jQuery

锋利的jQuery

单东林、张晓菲、魏然 / 人民邮电出版社 / 2009-6 / 39.00元

《锋利的jQuery》循序渐进地对jQuery的各种函数和方法调用进行了介绍,读者可以系统地掌握jQuery的DOM操作、事件监听和动画、表单操作、AJAX以及插件方面等知识点,并结合每个章节后面的案例演示进行练习,达到掌握核心知识点的目的。为使读者更好地进行开发实践,《锋利的jQuery》的最后一章将前7章讲解的知识点和效果进行了整合,打造出一个非常有个性的网站,并从案例研究、网站材料、网站结构......一起来看看 《锋利的jQuery》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具