Spring @Async使用

Stella981
• 阅读 490

@EnableAsync开启@Async注解功能

一、功能

@Async注解标记的方法可以使该方法异步的进行调用,如果在类上使用该注解,那么这个类的所有方法都会作为异步方法进行调用

注意点,Async注解是基于SpringAop进行实现的,所以在相同的一个类中,方法互相调用是不会起到异步执行的作用的,这里多说一句,任何使用spring aop代理实现的类,类内部方法调用代理肯定是不生效的

1、不需要返回值调用方式

@Component
public class MyTestService {

    @Async
    public void a() {
        System.out.println("a");
    }
    
}

2、指定使用线程池的调用方式,(如果这个线程池在spring容器中不存在则抛出bean找不到的异常)

@Component
public class MyTestService {

    @Async("myThreadPoolExecutor")
    public void a() {
        System.out.println("a");
    }
    
}

3、需要返回值的调用方式

@Component
public class MyTestService {

    @Async
    public Future<String> a() throws Exception {
        return new AsyncResult<String>("a");
    }

}

二、关于Async注解线程的使用情况

1、默认情况1

假设当前spring容器中没有任何自定义的线程池,Async注解也没有指定使用哪个线程池,那么默认使用org.springframework.core.task.SimpleAsyncTaskExecutor类,进行异步方法的调用,这个类本身内部并没有线程池的概念,既每次使用都会使用new Thread().start()的方式进行创建和执行。(如果频繁大量的创建线程必然会发生问题... ,实际情况肯定是需要使用线程池的)

2、默认情况2

假设当前spring容器中有自定义的线程池,那么它会使用当前容器中的线程池(注意这里指的有是说容器中只有1个线程池的情况,假如超过1个,那么还是按照默认情况1,进行执行)

3、指定默认使用的线程池,既没有在Async注解中指定使用哪个线程池,替代默认的线程使用规则

实现org.springframework.scheduling.annotation.AsyncConfigurer接口,下面代码是这个接口的描述

public interface AsyncConfigurer {

    /**
     * The {@link Executor} instance to be used when processing async
     * method invocations.
     */
    Executor getAsyncExecutor();

    /**
     * The {@link AsyncUncaughtExceptionHandler} instance to be used
     * when an exception is thrown during an asynchronous method execution
     * with {@code void} return type.
     */
    AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler();

}

第一个方法是获取执行调度的线程池(也就是指定Async注解使用的线程池)

第二个方法是,处理执行过程中发生的异常情况(这里所说的异常情况不包含线程池的rejectedExecution,而是你的业务方法自身抛出的异常)

下面是具体代码配置

@Configuration
public class AsyncPoolConfiguration implements AsyncConfigurer {
    
    @Autowired
    private AsyncTaskThreadPool asyncTaskThreadPool;

    @Override
    public Executor getAsyncExecutor() {
        return asyncTaskThreadPool;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}
点赞
收藏
评论区
推荐文章
郜小超 郜小超
1年前
用 async/await 来处理异步
一级标题昨天看了一篇vue的教程,作者用async/await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await已经被标准化,是时候学习一下了。先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思,异步函数也就意味着该函数的执行不会阻塞后面代码的执行。写一个async
刚刚好 刚刚好
6个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
Jacquelyn38 Jacquelyn38
1年前
你不可不知的JS面试题(第二期)
1、什么是继承?子类可以使用父类的所有功能,并且对功能进行扩展。新增方法改用方法(1)、ES6使用extends子类继承父类的方法。// 父类    class A        constructor(name)            this.name name;                getNa
晴空闲云 晴空闲云
6个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
5个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
Spring Boot使用@Async实现异步调用:自定义线程池
在之前的SpringBoot基础教程系列中,已经通过《SpringBoot中使用@Async实现异步调用》(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.didispace.com%2Fspringbootasync%2F)一文介绍过如何使用@Async注解来实现异
Wesley13 Wesley13
1年前
Java中异步注解@Async的陷阱
  或许,你在Java后端添加异步过程时会这样处理,然后摇摇大摆、灰溜溜地闪,而实际的运行结果却并不是我们期望的那样。那么,现在就将试验结果记录如下,以便少走弯路。  (一)在Controller层的公开接口直接添加@Async注解  当前端调用该种接口时会立刻结束,意味着开始即结束,不会在乎该异步接口返回的数据,其实这种接口只适合前端下发命令,后续
Stella981 Stella981
1年前
SpringBoot2.x版本整合Redis进行数据缓存
项目放在github:在缓存开发中,有两个重要的接口:在这里面:  @Cacheable:  如果用这个注解标注在方法上,那么方法的结果就会被缓存存起来,这个多用于在查询的时候进行使用    比如: publicusergetuser(Integerid) 这个方法用这个注解标注的话,通过id查到的内容就会杯存在缓存中进行保存
Easter79 Easter79
1年前
SpringBoot2.x版本整合Redis进行数据缓存
项目放在github:在缓存开发中,有两个重要的接口:在这里面:  @Cacheable:  如果用这个注解标注在方法上,那么方法的结果就会被缓存存起来,这个多用于在查询的时候进行使用    比如: publicusergetuser(Integerid) 这个方法用这个注解标注的话,通过id查到的内容就会杯存在缓存中进行保存
helloworld_28799839 helloworld_28799839
6个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue