从4.2.0.RC3升级到4.2.0.RELEASE时出现Spring异步问题 [英] Spring Async issue when upgrading from 4.2.0.RC3 to 4.2.0.RELEASE

查看:195
本文介绍了从4.2.0.RC3升级到4.2.0.RELEASE时出现Spring异步问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆