簡體   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