繁体   English   中英

请求范围的ApplicationEventListener无法接收事件

[英]Request-scoped ApplicationEventListener fails to receive events

我需要为每个请求注册一个单独的应用程序事件监听器。 侦听器的目的是捕获来自其他REST请求的事件,同时阻止侦听器的请求等待所有必需的事件进入。

我有这样的代码:

@Component
// @Scope(WebApplicationContext.SCOPE_REQUEST)
public static class WhistleEventListener implements ApplicationListener<WhistleEvent> {
  volatile Consumer<WhistleEvent> handler;
  @Override
  public void onApplicationEvent(WhistleEvent we) {
    final Consumer<WhistleEvent> h = handler;
    if (h != null) h.accept(we);
  }
}
@Autowired WhistleEventListener whistleEventListener;

此代码接收事件,但是一旦取消注释@Scope注释,它就会停止接收事件。

是否支持请求范围的应用程序事件侦听器,它们应该可以工作吗? 如果是这样,我可以做些什么让我的听众工作吗?

我怀疑你对应用程序事件调度机制有一个误解:事件是针对bean 定义而不是bean 实例调度的,并且每个bean定义现在被解析为一个实例,并且在上下文中被解析为事件发布。 这意味着您的事件将仅发送到属于发布事件的请求的请求范围的bean,但您希望通知所有当前请求的侦听器。

更一般地,范围的目的是隔离包含单独的bean实例的范围实例。 如果您不想要隔离,则应使用没有单独实例的范围,例如应用程序范围。

也就是说,要将事件分派给其他范围实例,您必须自己进行调度,例如:

@Component
public class WhistleEventMediator implements ApplicationListener<WhistleEvent> {
    // TODO: make thread safe
    final Set<Consumer<WhistleEvent>> consumers; 

    void subscribe(Consumer<WhistleEvent> c) { ... }

    void unsubscribe(Consumer<WhistleEvent> c) { ... }

    @Override public void onApplicationEvent(WhistleEvent we) {
        // delegate to subscribed consumers
    }
}

@Component 
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class WhateverBean implements Consumer<WhistleEvent> {
    @Inject
    WhistleEventMediator mediator;

    @PostConstruct
    void init() {
        mediator.subscribe(this);
    }

    @PreDestroy
    void destroy() {
        mediator.unsubscribe(this);
    }

    // handle whistle event
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM