使用spring boot 的 倆個註解時:
@EnableAsync
@Async
當一個線程多次重複調用時出現異常:
org.springframework.aop.interceptor.AsyncExecutionAspectSupport.getDefaultExecutor(AsyncExecutionAspectSupport.java:236) : Could not find unique TaskExecutor bean
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.core.task.TaskExecutor' available: expected single matching bean but found 2: applicationTaskExecutor,taskScheduler
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1148)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:413)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339)
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.getDefaultExecutor(AsyncExecutionAspectSupport.java:233)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.getDefaultExecutor(AsyncExecutionInterceptor.java:157)
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.lambda$configure$2(AsyncExecutionAspectSupport.java:119)
at org.springframework.util.function.SingletonSupplier.get(SingletonSupplier.java:100)
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.determineAsyncExecutor(AsyncExecutionAspectSupport.java:172)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.tuijie.goods.biz.jointstore.store.products.mountain.MountainServiceImpl$$EnhancerBySpringCGLIB$$893511f8.store(<generated>)
根據異常提示信息: 期望一個單列Bean 但是 找到了倆個相匹配的 bean.。所以報錯.
但是使用這個 Bean 是直接使用的 spirng 的,根本沒有在項目中定義,所以想要知道原因,需要去 生成Bean 的地方看看。
找到代碼的地址 org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration#applicationTaskExecutor
@Lazy
@Bean(name = { APPLICATION_TASK_EXECUTOR_BEAN_NAME,
AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME })
@ConditionalOnMissingBean(Executor.class)
public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) {
return builder.build();
}
原來 bean 創建的時候有倆個 name ,這倆個 name 剛好對應: applicationTaskExecutor, taskExecutor, 也對應倆個 BeanDefinition. Spring 在選用時候 不知道用哪個,報錯。
點進去 @Async 裏面說明
其 value 可以指定 Bean Definition 。加上
@Async(value = "applicationTaskExecutor")
運行項目。解決