从4.2.0.RC3升级到4.2.0.RELEASE时出现Spring异步问题 [英] Spring Async issue when upgrading from 4.2.0.RC3 to 4.2.0.RELEASE
问题描述
我有一个使用spring(4.2.x)工件的web应用程序spring-webmvc,spring-messaging,spring-websocket
I've a web application using the spring(4.2.x) artifacts spring-webmvc, spring-messaging, spring-websocket
我在下面@在我的spring config java类中启用*注释
I've the below @Enable* annotations in my spring config java class
@EnableWebMvc
@EnableWebSocketMessageBroker
@EnableAsync
@EnableMBeanExport
WebSocket用于向浏览器客户端广播消息。
并且很少有使用@Async注释的异步方法
WebSocket is used for broadcasting messages to browser clients. And there are few async methods annotated with @Async
该应用程序在春季版本4.2.0.RC3上正常运行。但是当我将其更改为GA版本4.2.0.RELEASE时,我在启动时得到以下异常。如果我删除@EnableAsync它工作正常,但我需要异步功能。
The application was working fine with spring version 4.2.0.RC3. But when I changed it to the GA release 4.2.0.RELEASE, I get the below exception on startup. If I remove @EnableAsync it works fine, but I need the async functionality.
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.core.task.TaskExecutor] is defined: expected single matching bean but found 4: clientOutboundChannelExecutor,messageBrokerTaskScheduler,clientInboundChannelExecutor,brokerChannelExecutor
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:366)
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor.setBeanFactory(AsyncAnnotationBeanPostProcessor.java:128)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1597)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1565)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:201)
org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:228)
org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:682)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:522)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:539)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
推荐答案
你的一个 @Configuration
必须实现 AsyncConfigurer
为 @Async
方法指定特定的 TaskExecutor
。
One of your @Configuration
must implement AsyncConfigurer
to specify the particular TaskExecutor
for @Async
methods.
否则,从 applicationContext
中选择哪一个是混淆的。
Otherwise it is in confuse which one to choose from the applicationContext
.
即使它与 RC3
一起使用也没关系它是正确的,因此该错误已修复 GA
。
Even if it worked with RC3
it doesn't matter that it is correct, hence the bug has been fixed for GA
.
更新
源代码 AsyncAnnotationBeanPostProcessor
如下所示:
Executor executorToUse = this.executor;
if (executorToUse == null) {
try {
// Search for TaskExecutor bean... not plain Executor since that would
// match with ScheduledExecutorService as well, which is unusable for
// our purposes here. TaskExecutor is more clearly designed for it.
executorToUse = beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
try {
executorToUse = beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, TaskExecutor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
throw new IllegalStateException("More than one TaskExecutor bean exists within the context, " +
"and none is named 'taskExecutor'. Mark one of them as primary or name it " +
"'taskExecutor' (possibly as an alias); or specify the AsyncConfigurer interface " +
"and implement getAsyncExecutor() accordingly.", ex);
}
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
// Giving up -> falling back to default executor within the advisor...
}
}
所以,我想在从RC3转到GA之间你已经有了一个 taskExecutor
bean。
So, I guess before in between moving from RC3 to GA you have had a taskExecutor
bean on the matter.
正如我们所看到的,StackTrace已经有了这样一个bean ......
As we see by you StackTrace there is such a bean already...
这篇关于从4.2.0.RC3升级到4.2.0.RELEASE时出现Spring异步问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!