最近在做重构,业务实现需要用到异步操作。随即在网上看了些关于spring异步操作的文章,最后决定用异步注解@Async结合线程池的方式来实现。
关于异步注解的使用以及注意事项在此不再详述,具体可参考:
1. spring @Async异步方法使用及原理说明
2. Spring异步任务@Async注解源码解析
首先自定义一个配置类:
在@Async注解中添加线程池名称
我们在调用该方法的时候,就默认使用我们自定义的线程池,开启异步操作了。
那么问题来了,为什么这样配置就使用我们自定义的线程池了呢?让我们继续往下看。
在AsyncExecutionInterceptor 类下的 invoke方法中。有一个获取线程池的方法: determineAsyncExecutor(userDeclaredMethod)。 这个方法就是获取我们自定义线程池的关键
继续往下看:
当执行到1处的时候,executors初始化之后是一个长度为0的Map。所以第一次取值为null。这时继续往下执行到2处:当我们配置了线程池,且在@Async注入了线程池,我们才会拿到自定义的线程池。
如果没有配置或者没有注入自定义的线程池,那么继续往下执行3:从beanFactory找一个线程池(如果有自定义配置的线程池,会从自定义的线程池中找到一个优先级高的返回。如果有多个,且优先级都一样,则会抛出异常"Could not find unique TaskExecutor bean",最终会创建一个默认的线程池)返回。
拿到线程池之后,执行到4,将该线程池与对应的method添加到executors中。当再有请求过来时,会去executors找是否存在该mothod的线程池,如果存在则直接拿出来使用,不存在则重复之前的操作。
以上就是我对spring异步任务@Async 结合线程池使用理解,如果有错误的地方,还望指正,共同进步