[英]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.