从4.2.0.RC3升级到4.2.0.RELEASE时出现Spring异步问题

Sub*_*aha 17 java spring spring-mvc executorservice spring-websocket

我有一个使用spring(4.2.x)工件的web应用程序spring-webmvc,spring-messaging,spring-websocket

我在spring config java类中使用了以下@ Enable*annotations

@EnableWebMvc
@EnableWebSocketMessageBroker
@EnableAsync
@EnableMBeanExport
Run Code Online (Sandbox Code Playgroud)

WebSocket用于向浏览器客户端广播消息.并且很少有使用@Async注释的异步方法

春季版本4.2.0.RC3的应用程序运行良好.但当我将其更改为GA版本4.2.0.RELEASE时,我在启动时得到以下异常.如果我删除@EnableAsync它工作正常,但我需要异步功能.

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)
Run Code Online (Sandbox Code Playgroud)

小智 24

在Spring应用程序上下文配置中添加bean

@Configuration
@EnableAsync
public class AppContext extends WebMvcConfigurationSupport {
    @Bean
    public Executor taskExecutor() {
        return new SimpleAsyncTaskExecutor();
    }
}
Run Code Online (Sandbox Code Playgroud)

我建议你参考linuxism.tistory.com/2076

如果以XML格式声明执行程序,则可以创建一个类并将其命名为TaskExecutor.然后,当Spring试图找到TaskExecutor bean时,它会找到这个bean.

@Component
public class TaskExecutor extends SimpleAsyncTaskExecutor {
}
Run Code Online (Sandbox Code Playgroud)


Art*_*lan 10

你的一个中@Configuration必须实现AsyncConfigurer指定特定TaskExecutor@Async方法.

否则很容易混淆哪一个applicationContext.

即使它与它一起工作RC3并不重要它是正确的,因此bug已被修复GA.

UPDATE

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...
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我想在从RC3到GA之间你已经有了一个taskExecutor问题.

正如我们在StackTrace中看到的那样,已经有了这样一个bean ...

  • 哪一个是RC3的默认值,它们之间有什么区别? (2认同)