SpringBoot使用异步 @Async :No qualifying bean of type 'org.springframework.core.task.TaskExecutor' available

SpringBoot使用异步 @Async :No qualifying bean of type ‘org.springframework.core.task.TaskExecutor’ available

使用 @Async 的过程空,出现异常

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.task.TaskExecutor' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
	at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.getDefaultExecutor(AsyncExecutionAspectSupport.java:228)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.getDefaultExecutor(AsyncExecutionInterceptor.java:156)
	at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.determineAsyncExecutor(AsyncExecutionAspectSupport.java:166)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:105)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)

看到这个异常,先不用慌。它其实不是异常信息,而只是一个 DEBUG 级别的信息。
意思是因为,没有找到合适的 TaskExecutor 实现类,作为异步任务的执行器,所以使用了默认的执行器。

解决

定义一个线程池

给线程池定义一个 bean name

import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


@Configuration
public class ThreadPoolTaskExecutorConfiguration {
	
	@Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)  // 预定义的 taskExecutor 的 bean name
	public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
		ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
		
		// TODO 针对系统和场景的优化参数
		
		// 线程池前缀
		threadPoolTaskExecutor.setThreadNamePrefix("task-executor-");
		return threadPoolTaskExecutor;
	}
}

使用 @Async的时候,通过 value 属性指定要使用的线程池 bean name

@Async(AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)