首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用spring配置异步和同步事件发布程序

如何使用spring配置异步和同步事件发布程序
EN

Stack Overflow用户
提问于 2014-10-09 10:23:50
回答 4查看 12.3K关注 0票数 12

我试图使用spring来实现一个事件框架,我知道spring事件框架的默认行为是同步的。但是,在春季上下文初始化过程中,如果它发现一个带有id applicationEventMulticaster的bean,则它的行为是异步的。

现在,我希望在我的应用程序中同时拥有同步和异步事件发布者,因为其中一些事件需要发布同步。我试图使用SysncTaskExecutor配置同步事件多播,但我找不到一种方法将它注入到AsyncEventPublisher的applicationEventPublisher属性中。我的spring配置文件如下所示

代码语言:javascript
复制
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" destroy-method="shutdown">
        <property name="corePoolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    </bean>  

    <bean id="syncTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor" />

    <bean id="customEventPublisher" class="x.spring.event.CustomEventPublisher" />
    <bean id="customEventHandler" class="x.spring.event.CustomEventHandler" />  
    <bean id="eventSource" class="x.spring.event.EventSource" /> 
    <bean id="responseHandler" class="x.spring.event.ResponseHandler" /> 
    <bean id="syncEventSource" class="x.spring.event.syncEventSource" /> 


    <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
        <property name="taskExecutor" ref="taskExecutor" />         
    </bean>    

    <bean id="syncApplicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
        <property name="taskExecutor" ref="syncTaskExecutor" />         
    </bean>    

有人能帮我吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-11-12 03:00:47

不,你不能这样做,spring initApplicationEventMulticaster只是一个,而BeanName必须是applicationEventMulticaster。所以你只需从下面的遗嘱执行人中选择一个:

- org.springframework.core.task.SyncTaskExecutor

- org.springframework.core.task.SimpleAsyncTaskExecutor

-你自己的遗嘱执行人: org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

无论如何,您都可以修改org.springframework.context.event.SimpleApplicationEventMulticaster以添加逻辑,然后可以控制是否需要同步/异步

代码语言:javascript
复制
    /**
 * Initialize the ApplicationEventMulticaster.
 * Uses SimpleApplicationEventMulticaster if none defined in the context.
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2019-09-13 19:10:25

我只是得自己解决这个问题。默认情况下,事件是异步发送的,除非您实现了标记接口,在我的例子中,我称之为SynchronousEvent。您也需要一个‘执行器’在您的配置(我省略了我的,因为它是相当定制的)。

代码语言:javascript
复制
@EnableAsync
@SpringBootConfiguration
public class BigFishConfig {

    @Autowired AsyncTaskExecutor executor;

    @Bean
    public ApplicationEventMulticaster applicationEventMulticaster() {
        log.debug("creating multicaster");
        return new SimpleApplicationEventMulticaster() {
            @Override
            public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
                ResolvableType type = eventType != null ? eventType : ResolvableType.forInstance(event);
                if (event instanceof PayloadApplicationEvent 
                        && ((PayloadApplicationEvent<?>) event).getPayload() instanceof SynchronousEvent) 
                    getApplicationListeners(event, type).forEach(l -> invokeListener(l, event));
                else 
                    getApplicationListeners(event, type).forEach(l -> executor.execute(() -> invokeListener(l, event)));
            }
        };
    }
...
票数 6
EN

Stack Overflow用户

发布于 2014-11-12 07:49:19

我不适合用堆叠溢出来编辑。请原谅我。

  1. SyncTaskExecutor

我不需要补充评论,你可以很清楚地知道。这是同步的。此执行器按顺序运行任务,并阻塞每个任务。

代码语言:javascript
复制
 public class SyncTaskExecutor implements TaskExecutor, Serializable {

/**
 * Executes the given {@code task} synchronously, through direct
 * invocation of it's {@link Runnable#run() run()} method.
 * @throws IllegalArgumentException if the given {@code task} is {@code null}
 */
@Override
public void execute(Runnable task) {
    Assert.notNull(task, "Runnable must not be null");
    task.run();
}

}

  1. SimpleAsyncTaskExecutor

这个类非常大,所以我只选择代码部分。如果您给threadFactory,将从此工厂检索线程,或将创建新线程。

代码语言:javascript
复制
    protected void doExecute(Runnable task) {
    Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));
    thread.start();
}
  1. ThreadPoolTaskExecutor

该类使用jdk5 5的当前pkg ThreadPoolTaskExecutor。但是spring封装了功能。弹簧在这种情况下很好,jdk7 6的电流和jdk7 7‘的电流pkg有一些不同。这将从ThreadPool获得线程并重用它,异步执行每个任务。如果您想知道更多细节,请参阅JKD源代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26276009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档